1

大家好,我一直在从Mark Ba​​tes Programming in coffeescript pdf这本书中学习咖啡脚本,尽管两者似乎都有相同的实现,但我一直对 javascript 的行为大发雷霆

示例-1

class Employee
  constructor: (@attributes)->
    for key, value of @attributes
      @[key] = value
  printInfo: ->
    alert "Name: #{@name}"
emp1 = new Employee
  name: "Mark"
  printInfo: ->
    alert "Hacked ur code !"

emp1.printInfo()

对应的javascript

var Emp, Employee, emp1, emp2;

Employee = (function() {

  function Employee(attributes) {
    var key, value, _ref;
    this.attributes = attributes;
    _ref = this.attributes;
    for (key in _ref) {
      value = _ref[key];
      this[key] = value;
    }
  }

  Employee.prototype.printInfo = function() {
    return alert("Name: " + this.name);
  };

  return Employee;

})();

emp1 = new Employee({
  name: "Mark",
  printInfo: function() {
    return alert("Hacked ur code !");
  }
});

emp1.printInfo();
这会提醒“你的代码被黑了!”

示例 2

class Emp
  constructor: (@attributes)->
  printInfo: ->
    alert "Name: #{@attributes.name}"
emp2 = new Emp
  name: "Mark"
  printInfo: ->
    alert "Hacked ur code"
emp2.printInfo()

对应的javascript

Emp = (function() {

  function Emp(attributes) {
    this.attributes = attributes;
  }

  Emp.prototype.printInfo = function() {
    return alert("Name: " + this.attributes.name);
  };

  return Emp;

})();

emp2 = new Emp({
  name: "Mark",
  printInfo: function() {
    return alert("Hacked ur code");
  }
});

emp2.printInfo();
这会提醒“姓名:马克”

区别在哪里?

4

2 回答 2

2

在第一个示例中,传递给构造函数 ( ) 的对象的所有属性attributes都被添加到当前实例中(这就是循环所做的)。实例属性隐藏原型属性,这就是printInfo你传递给构造函数的函数被执行的原因。您可以使用访问原始方法Employee.prototype.printInfo.call(emp1);

在第二个示例中,不会发生这种情况。该attributes对象只存在于attributes实例的属性中。要获得不同的警报,您需要编写emp2.attributes.printInfo();

于 2012-09-25T10:39:09.010 回答
1

在第一个示例中,以下代码向printInfo对象添加了一个属性:

_ref = this.attributes;
for (key in _ref) {
  value = _ref[key];
  this[key] = value;
}

密切注意this[key] = value;它向对象添加“直接属性”的位置,因此当 JS 引擎执行属性查找时,它会在对象本身中找到您的“printInfo”方法,因此它不会失败到原型链并调用您在那里定义的方法。现在,如果您使用Object.hasOwnProperty测试对象的printInfo属性,emp1您将看到它返回 true(这意味着它是直接属性对象,而不是从原型链继承的对象)。

参考Object.hasOwnProperty()hasOwnProperty 方法参考

于 2012-09-25T10:45:23.347 回答