nit*_*rma 7 javascript backbone.js
我是中等水平的javascript开发人员,他试图了解骨干库如何在内部工作,如果有人帮助我解决一些挑战,我将深深体会到.
所以这就是我的理解
Backbone中构造函数的基本定义是
Backbone.Model = function(attributes, options) { }
Run Code Online (Sandbox Code Playgroud)
然后他们使用通用扩展方法在我们的构造函数原型中添加常用功能.
_.extend(Backbone.Model.prototype, Backbone.Events, {...})
Run Code Online (Sandbox Code Playgroud)
现在直到这一部分我确切地知道发生了什么,并且很乐意通过以下代码实例化新对象
var user = new Backbone.Model()
Run Code Online (Sandbox Code Playgroud)
这是我发现具有挑战性的部分
当然,这不是我们在Backbone中实例化对象的方式,但我们使用extend方法
var Users = Backbone.Model.extend({});
var user = new Users()
Run Code Online (Sandbox Code Playgroud)
并在骨干代码中
Backbone.Model.extend = extend;
var extend = function(protoProps, classProps) {
var child = inherits(this, protoProps, classProps);
child.extend = this.extend;
return child;
};
var inherits = function(parent, protoProps, staticProps) {
var child;
if (protoProps && protoProps.hasOwnProperty('constructor')) {
child = protoProps.constructor;
} else {
child = function() {
return parent.apply(this, arguments);
};
}
_.extend(child, parent);
ctor.prototype = parent.prototype;
child.prototype = new ctor();
if (protoProps) _.extend(child.prototype, protoProps);
if (staticProps) _.extend(child, staticProps);
child.prototype.constructor = child;
child.__super__ = parent.prototype;
return child;
};
Run Code Online (Sandbox Code Playgroud)
请解释一下继承函数中发生了什么,以及扩展方法方法的好处是什么
Jon*_*ves 10
Underscore的extend函数将第二个参数中的成员(函数和属性)合并到第一个参数中.例如:
var reciever = {
name: "Jonny",
age: 29
};
var supplier: {
languages: [ "javascript", "actionscript" ];
sayHi: function () {
console.log("Hi, name name is " + this.name);
}
};
_.extend(receiver, supplier);
Run Code Online (Sandbox Code Playgroud)
执行上面的代码后,接收器对象将被扩充(修改),现在看起来像这样:
/*
{
age: 29,
languages: [ "javascript", "actionscript" ],
name: "Jonny",
sayHi: <<function>>
}
*/
console.dir(receiver);
Run Code Online (Sandbox Code Playgroud)
请注意,供应商对象保持不变,接收方对象从供应商处获得所有属性和功能.这个过程通常被称为mixin,用于避免重新声明函数(作为更广泛的编程原则的一部分,知道DRY - 不要重复自己).
现在对于Backbone的Model.extend函数,它作为工厂方法返回一个构造函数,该函数可用于创建模型的新实例,内部inherits函数执行大部分工作.该inherits函数将mixin概念更进一步,在所提供的对象和父对象之间创建一个继承链(在这个特定情况下,Backbone.Model对象).
var child;
if (protoProps && protoProps.hasOwnProperty('constructor')) {
child = protoProps.constructor;
} else {
child = function() {
return parent.apply(this, arguments);
};
}
Run Code Online (Sandbox Code Playgroud)
第一个代码块试图在提供的对象哈希中找到构造函数; 如果一个不存在,那么它会为你创建一个新的Constructor函数,它会自动将提供的参数传递给Backbone.Model自己的构造函数.
_.extend(child, parent);
Run Code Online (Sandbox Code Playgroud)
接下来,我们调用下划线的extend方法将所有属性和函数从提供的属性和函数的散列混合到构造函数中; 这可以确保您创建的每个实例都拥有自己的数据(例如:属性不是静态的,并且在您创建的所有实例之间共享).
ctor.prototype = parent.prototype;
child.prototype = new ctor();
if (protoProps) _.extend(child.prototype, protoProps);
if (staticProps) _.extend(child, staticProps);
child.prototype.constructor = child;
child.__super__ = parent.prototype;
Run Code Online (Sandbox Code Playgroud)
最后一个块是最令人兴奋的,它在新创建的Constructor函数的原型和parent(Backbone.Model)对象的原型之间创建了一个关系.通过这样做,构造函数返回的所有新实例将包含通常的主干模型方法(即:get和set),因为它们是从原型链中解析出来的.如果你想了解更多关于这个特定代码块的知识,Douglas Crockford关于Prototypal继承的文章是一个很好的起点.
这种方法的重点在于它允许您提供属性和函数的哈希值,结果构造函数将用作蓝图,例如:
var Person = Backbone.Model.extend({
name: "Jon Doe",
sayHi: function () {
console.log("Hi, my name is " + this.get("name"));
}
});
Run Code Online (Sandbox Code Playgroud)
现在,Person您实例化的每个对象都将具有name属性和sayHi函数,例如:
var dave = new Person();
dave.sayHi(); // "Hi, my name is Jon Doe"
dave.set("name", "Dave");
dave.sayHi(); // "Hi, my name is Dave"
// You can also supply properties when invoking the constructor.
var jimmy = new Person({ name: "Jimmy" });
jimmy.sayHi(); // "Hi, my name is Jimmy"
Run Code Online (Sandbox Code Playgroud)