康乐福 "new" 方法
Crockford "new" method
希望有人能帮我分解 Crockford 的 JS Good Parts 中的一段代码:
Function.method('new', function ( ) {
// Create a new object that inherits from the
// constructor's prototype.
var that = Object.create(this.prototype);
// Invoke the constructor, binding –this- to
// the new object.
var other = this.apply(that, arguments);
// If its return value isn't an object,
// substitute the new object.
return (typeof other === 'object' && other) || that;
});
我不明白的部分是当他使用应用调用模式创建对象时:
var other = this.apply(that, arguments);
如何执行 this 函数来创建新对象?
如果函数将是:
var f = function (name) {
this.name = "name";
};
调用方式:
var myF = f.new("my name");
创建对象?
首先注意Function.method
isn't a built-in JS method. It's something Crockford made up:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
因此,Function.method
方法调用基本上是这样做的:
Function.prototype.new = function() {
var that = Object.create(this.prototype);
var other = this.apply(that, arguments);
return (typeof other === 'object' && other) || that;
});
然后当你使用它时喜欢
f.new("my name");
它这样做:
- 首先,它创建一个继承自
f.prototype
(实例)的对象。
- 然后,它调用
f
并将该实例作为 this
值传递。
- 在这种情况下,这会将
name
属性 设置为实例。
- 此步骤不会创建任何新实例,该实例是在步骤 1 中创建的。
- 如果对
f
的调用返回了某个对象,则返回该对象。
否则,返回在步骤 1 中创建的实例。
用描述性名称重写
Crockford 的命名有点混淆,所以这里有相同的功能:
Function.prototype.new = function ( ) {
var theRealConstructor = this;
var freshObj = Object.create(theRealConstructor.prototype);
var freshObj_after_theRealConstructor =
theRealConstructor.apply(freshObj, arguments);
if(typeof freshObj_after_theRealConstructor === 'object'){
return freshObj_after_theRealConstructor;
} else {
return freshObj;
}
};
希望比 this
、other
和 that
更清楚。
详细说明和示例:
// this is a Waffle constructor
function Waffle(topping,ingredients){
this.toppings = topping;
this.ingredients = ['batter','eggs','sugar'].concat(ingredients);
}
// make the .new method available to all functions
// including our waffle constructor, `Waffle`
Function.prototype.new = function(){
// inside `Waffle.new`, the `this` will be
// `Waffle`, the actual constructor that we want to use
var theRealConstructor = this;
// now we create a new object, a fresh waffle,
// that inherits from the prototype of `Waffle`
var freshObj = Object.create(theRealConstructor.prototype);
// and call `Waffle` with it's `this` set to
// our fresh waffle; that's what we want the ingredients added to
var freshObj_after_theRealConstructor =
theRealConstructor.apply(freshObj, arguments);
// If we managed to make an object, return it!
if(typeof freshObj_after_theRealConstructor === 'object'){
return freshObj_after_theRealConstructor;
// otherwise, just return the pre-constructor fresh waffle
} else {
return freshObj;
}
};
// And to try it out
var myBreakfast = Waffle.new('syrup',['blueberries','chocolate']);
// and `myBreakfast` would look look like ↓↓
// {
// toppings: "syrup",
// ingredients:[
// "batter",
// "eggs",
// "sugar",
// "blueberries",
// "chocolate"
// ]
// }
希望有人能帮我分解 Crockford 的 JS Good Parts 中的一段代码:
Function.method('new', function ( ) {
// Create a new object that inherits from the
// constructor's prototype.
var that = Object.create(this.prototype);
// Invoke the constructor, binding –this- to
// the new object.
var other = this.apply(that, arguments);
// If its return value isn't an object,
// substitute the new object.
return (typeof other === 'object' && other) || that;
});
我不明白的部分是当他使用应用调用模式创建对象时:
var other = this.apply(that, arguments);
如何执行 this 函数来创建新对象?
如果函数将是:
var f = function (name) {
this.name = "name";
};
调用方式:
var myF = f.new("my name");
创建对象?
首先注意Function.method
isn't a built-in JS method. It's something Crockford made up:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
因此,Function.method
方法调用基本上是这样做的:
Function.prototype.new = function() {
var that = Object.create(this.prototype);
var other = this.apply(that, arguments);
return (typeof other === 'object' && other) || that;
});
然后当你使用它时喜欢
f.new("my name");
它这样做:
- 首先,它创建一个继承自
f.prototype
(实例)的对象。 - 然后,它调用
f
并将该实例作为this
值传递。- 在这种情况下,这会将
name
属性 设置为实例。 - 此步骤不会创建任何新实例,该实例是在步骤 1 中创建的。
- 在这种情况下,这会将
- 如果对
f
的调用返回了某个对象,则返回该对象。
否则,返回在步骤 1 中创建的实例。
用描述性名称重写
Crockford 的命名有点混淆,所以这里有相同的功能:
Function.prototype.new = function ( ) {
var theRealConstructor = this;
var freshObj = Object.create(theRealConstructor.prototype);
var freshObj_after_theRealConstructor =
theRealConstructor.apply(freshObj, arguments);
if(typeof freshObj_after_theRealConstructor === 'object'){
return freshObj_after_theRealConstructor;
} else {
return freshObj;
}
};
希望比 this
、other
和 that
更清楚。
详细说明和示例:
// this is a Waffle constructor
function Waffle(topping,ingredients){
this.toppings = topping;
this.ingredients = ['batter','eggs','sugar'].concat(ingredients);
}
// make the .new method available to all functions
// including our waffle constructor, `Waffle`
Function.prototype.new = function(){
// inside `Waffle.new`, the `this` will be
// `Waffle`, the actual constructor that we want to use
var theRealConstructor = this;
// now we create a new object, a fresh waffle,
// that inherits from the prototype of `Waffle`
var freshObj = Object.create(theRealConstructor.prototype);
// and call `Waffle` with it's `this` set to
// our fresh waffle; that's what we want the ingredients added to
var freshObj_after_theRealConstructor =
theRealConstructor.apply(freshObj, arguments);
// If we managed to make an object, return it!
if(typeof freshObj_after_theRealConstructor === 'object'){
return freshObj_after_theRealConstructor;
// otherwise, just return the pre-constructor fresh waffle
} else {
return freshObj;
}
};
// And to try it out
var myBreakfast = Waffle.new('syrup',['blueberries','chocolate']);
// and `myBreakfast` would look look like ↓↓
// {
// toppings: "syrup",
// ingredients:[
// "batter",
// "eggs",
// "sugar",
// "blueberries",
// "chocolate"
// ]
// }