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操作符new
new_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;
  };