我是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([]);
}
}
我的问题是:
function FbPicturesVM() {
...... some code ....
}
是否会在内存中创建fbPicturesVM的新实例?FbPicturesObj.fbPicturesVM
来电是否写得正确? (在代码优化方面)非常感谢。
答案 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对象中。