Javascript Function.prototype.bind示例
Javascript Function.prototype.bind示例,javascript,bind,Javascript,Bind,职能人员(arg){ 如果(this.name==未定义)this.name=arg?arg:“tom”; console.log(“Name:+this.Name”); } Person.prototype.setName=函数(值){ this.name=值; }; Person.prototype.getName=函数(){ 返回此.name; }; var myobj={name:“james”}; var new_func=Person.bind(myobj); new_func();
职能人员(arg){
如果(this.name==未定义)this.name=arg?arg:“tom”;
console.log(“Name:+this.Name”);
}
Person.prototype.setName=函数(值){
this.name=值;
};
Person.prototype.getName=函数(){
返回此.name;
};
var myobj={name:“james”};
var new_func=Person.bind(myobj);
new_func();//姓名:詹姆斯
var obj=新函数();//姓名:汤姆
log(obj.getName());//tom
您必须绑定函数本身,请尝试执行以下操作:
obj.getName().bind(myobj);
根据Mozilla的示例,在您使用
bind
时,您只能对函数调用bind,因为您正在使用Person
的相同函数体创建一个新的绑定函数
但是当您调用它来创建Person
的新的
实例时,您没有传递任何参数,因此它将使用默认参数Tom
创建一个新的元素作为名称
您可以从bind()文档中阅读以下内容:
bind()函数创建一个新函数(绑定函数),该函数的函数体(ECMAScript 5术语中的内部调用属性)和调用它的函数(绑定函数的目标函数)相同,并且该值绑定到bind()的第一个参数,不能被重写。bind()还接受在调用绑定函数时提供给目标函数的前导默认参数
在以下说明中:
1)
您正在使用myobj
作为此引用调用new_func()
2)
使用默认参数obj.name=“Tom”
创建实例
解决方案:
var obj = new new_func(myobj.name);
让我们分析一下代码
var myobj = {name : "james"};
var new_func = Person.bind(myobj);
new_func(); // Name: james
var obj = new new_func(); // Name: tom
console.log(obj.getName()); // tom
首先声明一个对象文字,其中有一个密钥,您打算将其用作未来新人的属性
接下来,将new_func
分配给Person和myObj的绑定。
这样,构造函数Person
就绑定到对象文本。但是,您正在使用该函数体创建一个新函数。当然可以调用它,但不会创建任何新对象
如果你只想给一个人一个名字,最好选择通过构造函数参数来实现
function Person (name) {
this.name = name;
}
并使用新的
var p1 = new Person("James");
console.log(p1.name);
但是,如果要创建另一个对象的现有对象实例,则应使用object.create([…].prototype)
为什么最后两个密码显示的是“汤姆”而不是“詹姆斯”
因为bind
会返回一个“绑定函数”,这在[[call]]被调用时是不同的,但不会改变[[construct]]离子的行为。bind
构造函数是不可能的,new
将始终创建一个新实例并忽略绑定值
您不应该在构造函数上使用bind
,它是用于方法的。要进一步阐明发生了什么,请参见以下示例:
function Person(arg) {
console.log("uninitialised", this);
this.name = arg;
}
var o = {name: "james"};
var bound = Person.bind(o);
var x = new bound("frank"); // uninitialised Person {}
console.log(x); // Person {name: frank}
console.log(o); // Object {name: james}
var x = bound("frank"); // uninitialised Object {name: james}
console.log(x); // undefined
console.log(o); // Object {name: frank}
如果我们检查polyfill的绑定
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
在代码中,我们可以看到基于以下条件使用对象调用apply
这是fNOP的实例吗?这是:oThis
,在我们的例子中,oThis
是myobj
,创建fNOP
是为了通过bind使新创建的方法的原型链接保持完整。因此,当我们使用new操作符newnew_func()
时,这将是fNOP的距离。因此,当前对象将是this
而不是myobj
,您可能应该阅读new
的文档:(此处:“使用指定参数调用构造函数函数Foo,并将其绑定到新创建的对象。”)Person
是一个函数
var myobj = Object.create(Person.prototype);
var myobj.name = "james";
console.log(myobj instanceof Person);
function Person(arg) {
console.log("uninitialised", this);
this.name = arg;
}
var o = {name: "james"};
var bound = Person.bind(o);
var x = new bound("frank"); // uninitialised Person {}
console.log(x); // Person {name: frank}
console.log(o); // Object {name: james}
var x = bound("frank"); // uninitialised Object {name: james}
console.log(x); // undefined
console.log(o); // Object {name: frank}
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};