pet*_*ter 23 javascript prototype
我想知道一旦它构建完成后我们还能改变它吗?
var O = function(someValue){
this.hello = function(){
return "hello, " + someValue;
}
}
O.prototype.hello = function(){
return "hhhhhhh";
}
var i = new O("chris");
i.hello(); // -> this still returns the old definition "hello, chris"
Run Code Online (Sandbox Code Playgroud)
javascript语句O.prototype.hello = function(){....}不会覆盖并重新定义hello函数行为.这是为什么 ?我知道如果你试图重用参数会有类型错误someValue.
// this will fail since it can't find the parameter 'someValue'
O.prototype.hello = function(){
return "aloha, " + someValue;
}
Run Code Online (Sandbox Code Playgroud)
我想知道为什么它允许在运行时添加功能
O.prototype.newFunction = function(){
return "this is a new function";
}
i.newFunction(); // print 'this is a new function' with no problem.
Run Code Online (Sandbox Code Playgroud)
但一旦定义,就不允许你更改定义.我做错什么了吗 ?我们如何覆盖和重新定义类中的函数?有没有办法重用我们之前传递的参数来创建对象?在这种情况下,someValue如果我们想要向其扩展更多功能,我们如何重新使用.
Viv*_*ath 23
使用时new,this构造函数内部的值指向新创建的对象(有关new工作原理的更多信息,请查看此答案和此答案).所以你的新实例i,有一个hello功能.当您尝试访问对象的属性时,它会沿着原型链向上走,直到找到它为止.由于hello存在于对象的实例上,因此无需走原型链来访问该hello返回的版本hhhhhhhh.从某种意义上说,您已经覆盖了实例中的默认实现.
如果不在构造函数内部分配hello,则可以看到此行为this:
var O = function(someValue) {
}
O.prototype.hello = function(){
return "hhhhhhh";
}
var i = new O("chris");
console.log(i.hello()); //this prints out hhhhhhh
Run Code Online (Sandbox Code Playgroud)
你正在做的事情是倒退.原型基本上提供了某种东西的"默认"形式,您可以在每个实例的基础上覆盖它.仅当在对象上找不到您要查找的属性时,才使用默认表单.也就是说,JavaScript将开始走向原型链,看看它是否能找到与您正在寻找的匹配的属性.它找到它,它将使用它.否则,它将返回undefined.
你在第一种情况下基本上拥有的内容如下:
Object.prototype.hello (not defined; returns "undefined")
|
+----O.prototype.hello (returns "hhhhhhhh")
|
+----i.hello (returns "hello, chris")
Run Code Online (Sandbox Code Playgroud)
所以当你这样做时i.hello,JavaScript会看到有一个hello属性i并使用它.现在,如果您没有明确定义hello属性,则基本上具有以下内容:
Object.prototype.hello (not defined; returns "undefined")
|
+----O.prototype.hello (returns "hhhhhhhh")
|
+----i.hello (is "undefined", so JavaScript will walk up the chain until
it sees O.prototype.hello, which does have a defined value
it can use.)
Run Code Online (Sandbox Code Playgroud)
这意味着您可以在原型中提供默认实现,然后覆盖它(在某种意义上它就像子类).您还可以做的是通过直接修改实例来修改每个实例的行为.hello你在原型上的版本是一种故障安全和后备.
编辑:你的问题的答案:
基于每个实例的覆盖意味着您将属性或函数附加到特定实例.例如,您可以这样做:
i.goodbye = function() {
return "Goodbye, cruel world!";
};
Run Code Online (Sandbox Code Playgroud)
这意味着此行为特定于该特定实例(即,仅针对i您可能已创建的任何其他实例).
如果你拿出来this,那你基本上有:
hello = function() {
return "hello, " + someValue;
}
Run Code Online (Sandbox Code Playgroud)
这等同于:
window.hello = function() {
return "hello, " + someValue;
}
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下,hello是对该函数的全局引用.这意味着hello没有附加到任何对象.
hello如果您没有this.hello = function() { .... };构造函数内部,则可以是未定义的.我还谈到了JavaScript用来尝试解析对象属性的一般过程.正如我之前提到的,它涉及走向原型链.
| 归档时间: |
|
| 查看次数: |
41356 次 |
| 最近记录: |