在对象中引用Javascript对象的正确方法

时间:2015-12-16 11:23:28

标签: javascript knockout.js

我是JavaScript的新手,我对我的应用中使用的以下旧版淘汰赛和JS代码不太确定:

file1.js:

% Initialize bonzai
bonzai(userInput(1),userInput(2)) = 1;

file2.js:

var FbPicturesObj = {
    fbPicturesVM: new FbPicturesVM(),
    initialize: function () {
        ko.applyBindings(FbPicturesObj.fbPicturesVM, $("#fb-albums")[0]);
        ko.applyBindings(FbPicturesObj.fbPicturesVM, $("#fb-album-photos")[0]);
    },
    Reset: function Reset() {
        FbPicturesObj.fbPicturesVM.albums([]);
        FbPicturesObj.fbPicturesVM.photos([]);
    }
}

我的问题是:

  1. 每次调用function FbPicturesVM() { ...... some code .... } 是否会在内存中创建fbPicturesVM的新实例?
  2. FbPicturesObj.fbPicturesVM来电是否写得正确? (在代码优化方面)
  3. 非常感谢。

3 个答案:

答案 0 :(得分:3)

function htmlify($string, $service) { if ($service == 'twitter') { $search_term = 'http://twitter.com/search?q='; $user_link = 'http://www.twitter.com/'; } else if ($service == 'instagram') { $search_term = 'https://instagram.com/explore/tags/'; $user_link = 'https://instagram.com/'; } if (!$search_term || !$user_link) return false; // Conver URLs $html_text = preg_replace("/([\w]+\:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/", "<a target=\"_blank\" href=\"$1\">$1</a>", $string); // Convert # tags $html_text = preg_replace("/#([A-Za-z0-9\/\.]*)/", "<a target=\"_blank\" href=\"$search_term$1\">#$1</a>", $html_text); // Convert @ tags $html_text = preg_replace("/@([A-Za-z0-9_\-\/\.]*)/", "<a target=\"_blank\" href=\"$user_link$1\">@$1</a>", $html_text); return $html_text; } 包含JavaScript对象的定义,更确切地说是“文字对象创建”。

在其中,每个File1.js对声明初始化一个新属性,因此在创建对象时代码只运行一次。例如propertyName: value

JavaScript对象的属性可以是函数,如下所示:fbPicturesVM: new FbPicturesVM()。在这种情况下,无论何时运行initialize: function () {...},,都将运行此功能。

FbPicturesObj .initialize的来电是正确的。此方法需要viewmodel对象和可选的DOM元素作为第二个参数。 jQuery表达式(不完全是)所选DOM元素的数组,因此ko.applyBindings根据$("#fb-album-photos")[0]的需要提取jQuery表达式的第一个DOM元素。

注意:正如您所怀疑的那样,至少可以说,定义模型的方式不是最好的。您可以使用Revealing Module Pattern,这样可以更轻松。

揭示模块模式

用几句话说:

ko.applyBindings

注意模式Immediately-Invoked Function Expression (IIFE)

var vm = (function() { // declare a function
   // create variables and functions
   var name = ko.observable();
   var age = ko.observable();
   var _privateVar = 'Yuhu'; // won't be revealed
   var incAge = function() {
      age = age + 1;
   };
   // reveal only what you want, by returning it in an object
   return {
     name: name,
     age: age,
     incAge: incAge
     // note that _privateVar is not exposed, but could be
   }
})(); // This invokes the function, so that it return the model

此模式定义了一个匿名函数,它返回一些东西。最后的var value = (function() {/*return something*/})(); 运行它,以便返回值,并存储在();

我推荐这种模式,因为它非常易于使用且容易出错。经典的原型继承,构造函数和类似的东西更难以使用。

您可以在视图模型工厂(类似于构造函数,但不是js构造函数)中轻松转换它,方法是删除最后的调用 - value - 并存储函数定义,以便您可以反复调用它。

()

答案 1 :(得分:0)

FbPicturesVM的构造函数仅在FbPicturesObj对象被实例化时调用(在您的示例中,这将是脚本包含在页面中时)。因此,就内存而言,您只有一个实例,然后您将引用传递给它(JS主要通过引用传递对象)。

我不太了解淘汰赛但是没有任何语法错误,传递一个对象和一个元素听起来正确的绑定代码。

答案 2 :(得分:0)

这个问题应该分开,因为第一个问题与Knockout无关,更多的是与对象文字如何与实例化对象相关联。

因此对于问题1,答案是“否”,因为FbPicturesObj保存了实例化的属性,FbPicturesObj.fbPicturesVM

请考虑以下事项:

var Person = function(name) {
	this.name = name
}

Person.prototype.sayName = function() {
	return this.name
}

var people = {
	fred : new Person('fred')
}

console.log(people.fred.sayName()); // returns 'Fred'

var people = {
	fred : new Person('jane')
}

console.log(people.fred.sayName()) // returns 'jane' and not 'fred'

var people = {
	fred : new Person('fred'),
  jane : new Person('jane')
}

console.log(people.fred.sayName()) // returns 'fred'
console.log(people.jane.sayName()) // returns 'jane'

在这种情况下,每次调用'person.fred'都会始终引用同一个实例,因为它保存在people对象中。