javascript中原型的含义
Meaning of prototype in javascript
我编写了从Person
继承reader
的短代码:
<script>
/* Class Person. */
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
}
var reader = new Person('John Smith');
alert(reader.getName());
</script>
或者,我可以删除Person.prototype.getName = function() { return this.name; }
的行,并在Person对象中创建它。例如
<script>
/* Class Person. */
function Person(name) {
this.name = name;
this.getName = function() { return this.name;}
}
var reader = new Person('John Smith');
alert(reader.getName());
</script>
在这两种情况下调用getName()
时,我都得到了相同的结果。那么它们有什么不同呢?
当您在原型上放置一些东西时,对象的每个实例都共享相同的方法代码。它们都在使用相同的函数实例。
当您简单地在this
上放置一个方法时,每个对象实例都有相同方法的副本。
使用CCD_ 6要有效得多。请注意,这就是为什么通常将方法放在原型上的原因,因为您通常希望所有实例使用相同的方法,但属性放在实例本身上,因为通常不希望所有实例共享相同的属性。
对于您的注释,如果您将一个方法放在对象的构造函数上,那么您实际上创建了一个"静态"方法。对象的任何实例都不会有该方法,它们都必须在构造函数上访问该方法。所以在你的情况下,Person.someMethod()
。
当您将方法放入构造函数并从该构造函数创建对象时,每个对象都带有自己的getName
函数。对于10个Person
实例,每个实例都携带自己的getName
,因此有10个单独的getName
函数。
如果将getName
放置在构造函数的原型中,那么相同的getName
函数将在所有实例中共享/继承。因此对于Person
的10个实例,每个实例都具有getName
,但仅引用1个getName
函数。
使用原型可以节省内存,因为该方法是跨实例共享的,所以只使用一个。
不同之处在于,当您将其放在原型上时,Person
的所有实例共享getName
的相同代码——您可以通过分配其他东西来更改Person
的所有实例上的getName
:
Person.prototype.getName = function() { return 'Mr Jones' };
此外,由于它们共享相同的代码,因此占用内存较少:getName
函数只有一个副本,而不是每个实例一个副本。
另一个区别是,您可以稍后将Person
设置为另一个类(比如Man
)的原型,并且它将继承属性/方法。
更新:这是一篇很好的文章,解释了原型的其他属性:https://stackoverflow.com/a/1534286/295262
不同之处在于,您进一步扩展了Person类,子类将不会继承getName()方法
编辑:我上面的说法不正确。刚刚在jsfiddle上测试。不管我们是在原型上还是在函数实例本身上定义一个方法,它都可用于链中的子类。
证据如下:http://jsfiddle.net/u8qrd/
我知道将这些方法附加到原型中会带来性能/内存方面的好处。除此之外,在继承方面没有任何行为差异吗?
(希望我在这里提问不会违反SO规则)
在基于类的单词中,通过prototype
和this
声明函数之间的区别如下:
原型:
实例的函数如下所示:
somefunc = function(){super()/*call the function of the super-class*/};
这个:
实例的函数如下所示:
somefunc = function(){/* Do same stuff as in the prototype func declared */};
现在,更改原型上的函数对实例没有影响。
当您将任何带有this.functionname
的函数添加到任何对象构造函数时,该构造函数创建的每个对象都会复制该函数,这也会占用内存。想象一下,若有几个对象是由同一个构造函数创建的,它需要多少内存。另一方面,当您使用cunstructorName.prototype.functionName
创建它时,函数在内存中只加载一次,并且每个对象共享相同的原型函数构造函数。这种方法可以加快代码的加载和操作速度,还可以节省大量内存。
在查看javascript原型之前,首先要了解几个概念:
- 构造函数 :因此,基本上,在javascript中,任何用新关键字调用的函数都充当构造函数,并返回一个对象
-
构造函数中的
this
关键字:因此,当您在函数中使用this
关键字,然后用new
关键字调用该函数时。this
关键字与返回的对象隐式绑定,如果将任何属性或方法分配给this
关键字,它将被分配给返回的对象。如下面提供的代码示例所示:
function foo(){
this.name="foo"
this.greet=function(){
console.log("Good morning")
}
}
const obj=new foo()
所以现在,如果你想让某个属性对所有创建的对象保持不变,那么为每个对象实例分配该属性或方法单独的内存是没有意义的。相反,您可以在构造函数的原型属性上定义它,然后使用该构造函数创建的所有对象都可以访问它。例如,在上面给出的示例中,greet方法将对所有对象保持不变,因此我们可以重构如下所示:
function foo(){
this.name="foo"
}
foo.prototype.greet=function(){
console.log("Good morning")
}
const obj=new foo()
这不是继承
有些人可能会把它描绘成一种遗产。但不要混淆,这不是你的传统遗产。但取而代之的是授权。因此,在上面的代码示例中,当您尝试将greet
方法w.r.t调用为obj
时。口译员说他找不到它。所以他会看看这个物体指向哪个原型。它将指向foo
函数的原型。因此,它将对其进行研究,并在其中找到定义的greet
方法。
- 使用“;这个“;JavaScript原型方法中的关键字
- 如何从对象的原型方法访问JavaScript对象属性
- Node.js中的JavaScript原型对象效率
- 为什么要返回'这'在导致循环的JavaScript原型中
- 原型和用法 Javascript
- JavaScript对象不是从原型链继承的
- javascript对象原型与jquery冲突
- 原型Javascript中的错误“;类别“-不是函数和未定义的变量
- 从字符串原型javascript获取字符串值
- 原型JavaScript Event.observe-如何观察可能存在或不存在的元素
- 与原型javascript冲突
- 为什么原型JavaScript在这种情况下不起作用
- 使用原型JavaScript - 最佳实践
- 添加到另一个原型实例的原型:JavaScript
- 函数.原型Javascript
- 如何在选定的原型javascript中更新基于第一选择框的第二选择
- 原型Javascript框架-获取PHP响应
- 如何访问类原型Javascript中定义的事件处理程序中的类成员变量
- 原型 javascript 不显眼的点击事件添加到按钮
- 字符串vs数组原型Javascript