在这个例子中,我的对象方法是如何被黑客入侵的?

时间:2012-09-25 10:09:40

标签: javascript coffeescript

大家好我从书中学习coffeescript 马克贝茨编程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();
 This alerts "Hacked ur code !"

例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();
 This alerts "Name: Mark"

区别在哪里?

2 个答案:

答案 0 :(得分:2)

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

访问原始方法

在第二个例子中,没有这样的事情发生。 attributes对象只存在于实例的attributes属性中。要获得不同的提醒,您需要撰写emp2.attributes.printInfo();

答案 1 :(得分:1)

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

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

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

Object.hasOwnProperty()参考: hasOwnProperty method reference