crz*_*777 15 javascript ember.js
我在阅读emberjs.com上的文档时感到困惑 http://emberjs.com/documentation/#toc_reopening-classes-and-instances
在上面的页面上,它解释如下.
Person.reopen({
// override `say` to add an ! at the end
say: function(thing) {
this._super(thing + "!");
}
});
Run Code Online (Sandbox Code Playgroud)
如您所见,重新打开用于向实例添加属性和方法.但是当您需要创建类方法或将属性添加到类本身时,您可以使用reopenClass.
Person.reopenClass({
createMan: function() {
return Person.create({isMan: true})
}
});
Person.createMan().get('isMan') // true
Run Code Online (Sandbox Code Playgroud)
虽然解释说"reopen用于向实例添加属性和方法.",我认为上面显示的两个示例都讨论了如何创建类方法或将属性添加到类本身,而不是实例.
我误解了它的内容吗?我不是一个经验丰富的程序员,所以我可能会被误解......
如果我被误解,请解释何时使用reopen和reopenClass.
提前致谢!
Jul*_*ton 17
文档并没有很好地解释这一点,但这是一个非常棘手的主题.
顺便说一下,它现在位于:http: //emberjs.com/guides/object-model/reopening-classes-and-instances/
谈论面向对象编程的一个问题是它经常被解释为: - 对象是对象.对象是类的实例. - 类是对象. - 实例是对象,并且有一个类.
这个解释对任何人都没有帮助,似乎是一个递归问题(即引用无止境......对象是一个类的实例,是一个对象......(重复)).
我更喜欢以下列方式推理:
当人们编写代码时,他们经常描述类和实例.类是一种东西.水果是一个阶级的例子.我们这里不是在谈论一件特别的事情,我们谈论的是整个"阶级"事物(因此得名).
请注意,它不是真正的类.它只是在"现场"和"在计算机内存中"才真实.在那之前,它是一个类的描述.通常当人们编写代码时,他们会在文本文件中写入文本,而这只是计算机内部实际代码的描述,当计算机将其解释或编译为机器代码时.
当你意识到一个类实际上它本身就是一个描述时,会发现棘手的一点.它描述了一系列潜在的真实物体.
在计算机中,当您创建"苹果"时,这就是一个实例.它也是一个对象.它的类是Apple,它在计算机中也是一个真实的实时对象.当我们谈论Apple时,这是一个想法.它在现实中并不存在,但是对于计算机来说它必须使它存在于现实中,所以"Apple"是一个具体的,真实的对象,即使它也是一个抽象.
我认为最后一点是人们对物体感到困惑的原因.类是抽象,但为了使计算机能够对它们进行交谈和推理,它们必须是真实的.所以,我们决定......"阶级意味着抽象,实例意味着真实"......
麻烦的是,我们有继承...它带来了抽象层次的想法...所以在我们的水果模型中,你有特别的苹果在你面前,也是一个水果,而水果也是一种食物.事实上,除非我们说"这种食物,这种苹果",或"世界上所有的食物",或"你妈妈的千层面",否则食物实际上不是作为一种东西或一组东西存在,那么这是一个抽象的想法...
因此,在我们面向对象的计算机中,我们说"定义食物是一种物体,现在定义果实是一种食物,现在定义苹果是一种水果,现在定义这个苹果,这是一种苹果".
现在这意味着: - 对象是Food的类,Food是Object的一个实例,Food也是一个类! - 食物是水果的类,水果是食物的一个实例,水果本身也是一个类! - Fruit是Apple的类,Apple是Fruit的一个例子,而Apple也是一个类! - Apple是你的苹果类,你的苹果是Apple的一个实例(因此也是Fruit,Food和Object!).但是,它不是一个类,它只是一个对象.
为了推理你的苹果,我们说这是一个对象(注意小写的o),它也是一个苹果,一个水果和一个食物,而且...这里是踢球者......它也是一个对象.
所以现在我们希望我们能够理解你的苹果是一个物体,一个实例(苹果,水果,食物和物体),一个苹果,一个水果,一个食物和一个物体,但它不是一个类.
所以...如果你向一个类添加一个实例方法,那么它将不会在类中可用,但它将在该类的所有实例上可用.如果添加一个类方法,它将在该类(和子类)上可用.因此,如果向Apple添加实例方法,那么apple的所有实例都将能够运行该方法.但是,如果你只为你的苹果添加方法,那么只有你的苹果会有这种方法.我的苹果不会.如果向Apple添加一个类方法,那么只有Apple类才能运行该方法(方便的是,您也可以通过它的所有实例访问).类方法适用于不更改PARTICULAR实例的事物.实例方法适用于改变特定实例(通常)的事物.属性/属性也是如此.你不会在名为"Apple color"的Apple类上创建一个类方法,因为这听起来像是与特定的 Apples(即实例)有关.希望有点清楚:)
在我尝试了reopen()和reopenClass()之后,我发现了它们之间的区别。
这是我的实验结果。
var Person = Ember.Object.extend({
name:"",
alive:true,
sayHi:function(){
alert("hi");
}
});
Person.reopenClass({
age:30,
sayHo:function(){
alert("ho");
}
});
Person.reopen({
height:180,
sayYo:function(){
alert("yo");
}
})
var person = Person.create({
name:"Tom"
});
//person.reopenClass();//error!!
person.reopen({
sayWhat:function(){
alert("what!?");
},
weight:100
});
console.log(Person.alive);//undefined
console.log(Person.age);//30
console.log(Person.height);//undefined
console.log(Person.weight);//undefined
console.log(person.alive);//true
console.log(person.name);//Tom
console.log(person.height);//180
console.log(person.weight);//100
person.sayHi();//it works
//person.sayHo();//it doesn't work
Person.sayHo();//it works
person.sayYo();//it works
//Person.sayYo();//it doesn't work
//Person.sayWhat();//it doesn't work
person.sayWhat();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4735 次 |
| 最近记录: |