JS中的对象-原型
提到JS中的对象,我们就不得不提一提JS对象中的原型。我们知道,JS是可以面向对象编程的语言,通常,在面向对象中,继承关系都是通过类来实现的。但是,请记住,在JS中,并没有类的概念。在JS的设计之初就没有类,没有类,没有类。那么,既然JS中没有类,那么,在JS中,继承是通过什么来实现的呢?答案就是原型。在JS中有一种叫做原型的东西。而且每个对象都有原型,对象之间通过原型来彼此联系,形成彼此之间的关系。就像一个链条一样。所以,JS中就有一个叫原型链的术语。
原型
在JS中,每个实例对象(object)都有一个私有属性(称之为__proto__)指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象,层层向上直到一个对象的原型对象为null。而null没有原型,并作为整个原型链的最后一个环节。
在JS中,对象之间的关系就是通过这样的原型链来联系的。对象之间可以通过原型链来实现继承。其中,对象可以继承原型中的属性和方法。其中,原型中的属性和方法可以为实例所共享。JS对象有一个指向原型对象的链。当试图搜索一个对象的属性时,它不仅仅在对象上搜索,还会在原型链上搜索,一层层搜索,知道找到一个名字匹配的属性或者到达原型链的末尾。而且,一旦搜索到匹配的属性,在原型链上的搜索就会停止。因此,原型链上的属性具有屏蔽性。比如在对象中已经存在一个属性'name',那么,当检索'name'属性的时候,因为对象中存在'name'属性,就不会再原型链上继续搜索。如:
var student={
name:'Jack',
sex:1
}
var person={
name:'James',
sex:1,
age:12
}
student.__proto__ = person;
student.name;//Jack
delete student.name;
student.name;//James
student.age;//12
需要注意的是,在JS中,每个对象都有自己的__proto__,但是,只有函数才会拥有prototype;其中,__proto__是一个非标准的属性,但是在各个主流浏览器里都已经得到了实现,到了ES6开始,可以使用Object.getPrototypeOf()和Object.setPrototypeOf()来实现相同的效果。因为__proto__是各个浏览器的实现,其他JS环境可能没有实现,所以跨平台使用的时候请慎重。
由于JS语言的动态性,当JS原型中得到某个属性或者方法修改以后,所有继承自该原型的示例中相应的属性或方法也会立刻得到相应的改变。这一点需要特别注意,因为在修改原型中的属性或方法的时候,可能会意外导致实例中的属性或方法改变。虽然,在ES6中,拥有了像class这样的关键字,但是,这也只是一个语法糖,并不存在真正的类,继承原理还是原型继承。所以,在JS开发的时候,要习惯于使用JS的原型继承的思想。而不是在JS中套用其他语言中类的继承机制。
Foo = {
init: function (who) {
this.me = who;
},
identify: function () {
return "I am " + this.me;
}
};
Bar = Object.create(Foo);
Bar.speak = function () {
alert("Hello, " + this.identify() + ".");
};
var b1 = Object.create(Bar);
b1.init("b1");
var b2 = Object.create(Bar);
b2.init("b2");
b1.speak();
b2.speak();
这里使用的就是JS的原型继承的思想,也是一种就做行为委托的方式,这种方式将Bar和Foo在一定的程度上进行了解耦,并没有在形式上使用类的语法。这样的行为更加符合JS的设计和思路,对各个对象之间的关系也更加清晰明了。
今天关于JS中原型的内容就先进行到这里。大家有什么疑问,请在留言区留言。或者在JS方面有什么需要了解的也请大家积极留言。希望大家可以相互分享工作和学习中的知识和见识。
领取专属 10元无门槛券
私享最新 技术干货