大家好我从书中学习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"
区别在哪里?
答案 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