JavaScript中的Parisitic继承

Set*_*hen 3 javascript

观看道格拉斯·克罗克福德关于高级JavaScript的讲座,他提出了寄生继承的想法,这本质上是构造函数调用其他构造函数来修改有问题的对象.这是他的代码:

function gizmo(id, secret) {
  secret = secret || {};
  secret.id = id;
  return {
    toString: function () {
      return "gizmo " + secret.id;
    }
  };
}

function hoozit(id) {
  var secret = {},
      that = gizmo(id, secret);
  that.test = function (testid) {
    return testid === secret.id;
  };
  return that;
}

var myHoozit = hoozit(20);
console.log(myHoozit.test(20)); //returns true
Run Code Online (Sandbox Code Playgroud)

我理解代码,这里没有什么难以理解的.混乱发生在hoozit函数中.如果你没有设置,secret = {}你就不会得到一个true被退回的.

这是令人困惑的,因为在gizmo函数中,你会看到secret = secret || {}哪个应该为我们处理这个......但事实并非如此.

为什么不能正常工作的是短路(secret = secret || {}在)gizmo当不被传递的第二参数函数hoozit功能(在器和Firefox符)??

Fel*_*ing 5

为什么不能正常工作的是短路(secret = secret || {}在)gizmo当不被传递的第二参数函数hoozit功能(在器和Firefox符)??

很简单,因为您无法访问secret内部,that.test因为它在该范围内不存在:

function hoozit(id) {
  var that = gizmo(id);
  that.test = function (testid) {
    // secret is not defined in this or in any higher scope
    // hence you get a refernece error
    return testid === secret.id;
  };
  return that;
}
Run Code Online (Sandbox Code Playgroud)

唯一secret存在的对象是gizmo函数的本地对象.


如果你定义它并且只是不传递给它gizmo,那么secret = secret || {}将评估为secret = {},即在gizmo函数内部创建一个新对象.该值只能在gizmo函数内访问,并且与函数中的secret变量完全无关hoozit.secret里面的对象与中的对象gizmo不同hoozit.

function hoozit(id) {
  var secret = {},      // secret object is created here
      that = gizmo(id);
  that.test = function (testid) {
    // you never set `secret.id`, hence the comparison results in `false`
    return testid === secret.id;
  };
  return that;
}
Run Code Online (Sandbox Code Playgroud)

没有任何问题secret = secret || {},它按预期工作.