[英]How do I create an unitialized object in javascript?
我正在使用JavaScript更改iframe中的頁面的向導。 我想為向導的每個頁面創建一個對象,並引用下一頁和上一頁。
編輯:下面發布的代碼不起作用。 執行后,actionOne.nextAction等於{}。
var actionOne = {};
var actionTwo = {};
actionOne = {
url: 'actionOneUrl.htm',
prevAction: null,
nextAction: actionTwo,
doDisplay: function(){
$('.label').html('Action One');
}
}
actionTwo = {
url: 'actionTwoUrl.htm',
prevAction: actionOne,
nextAction: null,
doDisplay: function(){
$('.label').html('Action Two');
}
}
問題是我不知道如何正確設置下一個和上一個參考。 可能有一個相對簡單的解決方案,但我不確定要搜索什么。 創建所有頁面后,我可以設置引用,但是這樣做很麻煩。 創建對象時有沒有辦法做到這一點?
對於您想做的事情,您將需要在JavaScript中使用面向對象的方法。 這將允許您將引用分配給對象的新實例 。 例如,這有效:
function Action(url, name){
this.url = url;
this.prevAction = null;
this.nextAction = null;
this.name = name;
}
Action.prototype.doDisplay = function(){
$(".label").html(this.name);
}
var actionOne = new Action('actionOneUrl.html', 'Action One');
var actionTwo = new Action('actionTwoUrl.html', 'Action Two');
actionOne.nextAction = actionTwo;
actionTwo.prevAction = actionOne;
console.log(actionOne.nextAction);
編輯:因此,OP要求實現一個在新添加的動作之間自動設置這些鏈接的實現。 因此,這是一個雙向鏈接列表實現:
function ActionList(){
this.head = null;
this.tail = null;
}
ActionList.prototype.doDisplay = function(index){
var node = this.getNode(index);
console.log(node.name);
}
ActionList.prototype.getNode = function(index){
var current = this.head,
c = 0;
while(c < index && current !== null){
current = current.nextAction;
c++;
}
return current;
}
ActionList.prototype.add = function(url, name){
var node = {
url: url,
name: name,
nextAction: null,
prevAction: null
};
if(this.head === null){
this.head = node;
this.tail = node;
}
else{
this.tail.nextAction = node;
node.prevAction = this.tail;
//move tail to new node
this.tail = node;
}
}
var actionList = new ActionList();
//Each add automatically sets up links between the two
actionList.add('actionOneUrl.html', 'Action One');
actionList.add('actionTwoUrl.html', 'Action Two');
console.log(actionList.getNode(1));
actionList.doDisplay(1);
這是一個非常簡化的示例,但是類似下面的結構將避免需要手動引用您的下一個/上一個操作...讓應用程序邏輯根據用戶的輸入來查找要做什么。
UnderscoreJS的where
函數http://underscorejs.org/#where在這里有用
var dataFromServer = [
{id:"1", name: "First Page", nextId:"2"},
{id:"2", name: "Second Page", nextId:"3", prevId: "1"},
.....];
var actions = [];
var Action = function(data) {
this.doNextURL = function() {
//find action with id= data.nextId;
var actionToDo = _.where(actions, {id: data.nextId})[0];
window.location.href = actionToDo.url; //or something... a callback parameter, or returning the action rather than doing the 'ui logic' here would be better real world
}
}
for(var i = 0; i < dataFromServer.length; i+=1){
actions.push(new Action(dataFromServer[i]));
}
當你做
actionTwo = {
// ...
}
您正在為actionTwo
分配一個新值。 它不再引用您在var actionTwo = {};
分配的對象var actionTwo = {};
因此不會引用您在其中使用的對象
actionOne = {
// ...
nextAction: actionTwo,
// ...
}
最簡單的方法是只初始化兩個對象,然后在以后將它們分配給正確的屬性:
var actionOne = {
url: 'actionOneUrl.htm',
prevAction: null,
nextAction: null,
doDisplay: function(){
$('.label').html('Action One');
}
};
var actionTwo = {
url: 'actionTwoUrl.htm',
prevAction: null,
nextAction: null,
doDisplay: function(){
$('.label').html('Action Two');
}
};
actionOne.nextAction = actionTwo;
actionTwo.prevAction = actionOne;
如果要對多個操作執行此操作,則應考慮使用構造函數,如joeltine在他的答案中所示 。
要了解有關對象的更多信息,請查看MDN-使用對象 。
嘗試以下操作:不要為actionOne,actionTwo創建NEW對象,而是將代碼保持原樣-而是為已存在的對象(由前兩行創建)分配給對象屬性。
var actionOne, actionTwo;
actionOne = {
url: 'actionOneUrl.htm',
doDisplay: function(){
$('.label').html('Action One');
}
};
actionTwo = {
url: 'actionTwoUrl.htm',
doDisplay: function(){
$('.label').html('Action Two');
}
};
actionOne.prevAction = null; //could also be set above
actionOne.nextAction = actionTwo;
actionTwo.prevAction = actionOne;
actionTwo.nextAction = null; //could also be set above
您的問題是一個很好的問題 -不要讓其他人告訴:)即使在相當多的JS背景下,對象屬性也指向變量(字面量)指向的對象並不明顯。執行對象創建語句,而不是執行變量本身(在這種情況下,您的示例將起作用)。
而且,即使它被投票贊成,也請忽略MVC模式。 MVC沒什么問題(有時),但這是一個非常非常基本的Javascript問題,這些模式問題在一個與您有趣的小問題完全不同(更高)的水平上發揮了作用。
一些背景:以對象為值的Java腳本執行引擎變量的內部深處是指針(C / C ++背景知識對於理解Java腳本非常有用,因為JS引擎是用Java編寫的)。 因此,當您將此類變量的值分配給對象屬性時,它不會指向該變量,而是將接收該變量當時具有值的指針。 這意味着,如果變量被分配了一個新對象,指向內存中的另一個位置,則object屬性將始終指向舊對象。 如果它指向變量,它將找到一個指向新對象的指針。 如您所見,回答您的問題使我們深入了解Javascript引擎實際上是如何在很低的水平上工作的:)
所有其他答案肯定也可以解決您的迫在眉睫的問題,但是我相信知道這一點背景最終會更加肥沃。 除了嘗試給出可行的答案外,有時還值得調查實際發生的事情... :)
基本類型直接存儲在變量中,對象的變量實際上是指針。 new String(“ foo”)是一個對象(字符串),“ foo”是一個原始類型(字符串)。
在Java語言中調用函數時,請牢記完全相同的問題! 從技術上講,它總是按值進行調用-但是,當變量是指向對象的指針時,值就是指針,將變量作為參數分配給變量時必須考慮該指針。
當使用{}
對象常量來定義對象時,您將使用Object構造函數創建一個新的對象實例。
以下從Object構造函數創建兩個新的對象實例:
var actionOne = {}; // object instance 1
var actionTwo = {}; // object instance 2
下一部分將通過Object構造函數創建另一個新的對象實例 (第三個對象實例),並添加幾個屬性。 actionOne.nextAction
指向的對象實例actionTwo
(其中沒有任何自己的屬性)。
actionOne = {
url: 'actionOneUrl.htm',
prevAction: null,
nextAction: actionTwo,
doDisplay: function(){
$('.label').html('Action One');
}
} // object instance 3
因此,現在,當您聲明actionTwo = {....}
它會創建帶有多個新屬性的第四個對象實例 。 actionOne.prevAction
仍指向您創建的第二個對象實例(但不再使用全局變量actionTwo進行引用)。
要記住的關鍵是對象文字{}
使用Object構造函數創建新的對象實例,並且您創建的屬性在聲明它們時引用該對象實例。
每個人似乎真的使這個問題復雜化了。
function Wizard(o) {
return { url:o.url, doDisplay:function() { $('.label').html(o.html); } };
}
var wizards = [{url: 'actionOneUrl.html', html:'Action One'},
{url: 'actionTwoUrl.html', html:'Action Two'}].map(Wizard);
// wizards now contains an array of all your wizard objects
wizards.reduce(function(p,c) { c.prevAction = p; return p.nextAction = c; });
// prevAction and nextAction now point to the right places
不,您不能,但是您可以保留空對象並填充它們:
var actionOne = {};
var actionTwo = {};
actionOne.url = 'actionOneUrl.htm';
actionOne.prevAction = null;
actionOne.nextAction = actionTwo;
...
但這很丑。 我建議使用如下函數填充它們之間的鏈接:
function chain() {
var i, prev, curr;
for(i = 0; i < arguments.length; i++) {
curr = arguments[i];
if(prev) {
prev.nextAction = curr;
curr.prevAction = prev;
}
else {
curr.prevAction = null;
}
prev = curr;
}
if(curr) curr.nextAction = null;
}
var actionOne, actionTwo;
actionOne = {
url: 'actionOneUrl.htm',
doDisplay: function(){
$('.label').html('Action One');
}
}
actionTwo = {
url: 'actionTwoUrl.htm',
doDisplay: function(){
$('.label').html('Action Two');
}
}
chain(actionOne, actionTwo);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.