原型链结构

JavaScript主要是通过原型链来实现继承的。所以,通过这篇文章先大概了解一下原型链结构吧~

通过学习面向对象中的原型,我们可以知道以下概念:

  • 每个构造函数都有原型结构
  • 每个对象都会有构造函数
  • 每个构造函数的原型都是一个对象

所以,我们可以得出以下结论:

  • 这个原型对象也有构造函数
  • 这个原型的构造函数也会有原型对象

这样就会形成一个链式结构,称为 原型链 。

1.原型链结构的基本形式
function Person(name){
    this.name = name;
}
var p = new Person;

链结构:
p –> Person.prototype –> Object.prototype –> null

属性搜索原则:
当访问一个对象的成员时,会先在自身找有没有,如果找到直接使用;如果没有找到,则去当前对象的原型对象中查找,如果找到直接使用;如果没有找到,继续找原型对象的原型对象,如果找到直接使用;如果没有找到,继续向上查找,直到Object.prototype,如果还是没有找到,则报错。

2. Object.prototype成员:

1)constructor:原型对象内的一个属性,指向该对象相关的构造函数

在使用新的对象替换掉默认的原型对象之后,原型对象中的constructor属性会变成object 。为了保证整个 “构造函数–原型–对象–” 之间关系的合理性,应进行如下操作:
在替换原型对象的时候,在新的原型对象中手动添加constructor 属性。

function Person(){
}
console.log(Person.prototype.constructor);//f Person(){}
Person.prototype = {
    constructor : Person
};
console.log(Person.prototype.constructor);//f Person(){}

2)hasOwnProperty:用来判断对象本身存在于实例中还是原型中,存在于实例时会返回true

function Person() {
}
Person.prototype.name = "aaa";
Person.prototype.age = 22;
var p1 = new Person(); 
var p2 = new Person();

console.log(p1.hasOwnProperty("name")); //false 此时p1的name属性来自原型

p1.name = "ccc";
console.log(p1.name); //ccc
console.log(p1.hasOwnProperty("name"));  //true 此时p1的name属性来自实例

console.log(p2.name); //aaa
console.log(p2.hasOwnProperty("name")); //false p2的name属性来自原型

delete p1.name;
console.log(p1.name); // aaa
console.log(p1.hasOwnProperty("name")); //false 此时p1的name属性来自原型

3)propertyEnumerable:用来检测属性是否属于某个对象的,如果检测到了,返回true,否则返回false.

  • 这个属性必须属于实例的,并且不属于原型.
  • 这个属性必须是可枚举的,也就是自定义的属性,可以通过for-in循环出来的.

只要符合上面两个要求,就会返回true。

function Person() {
    this.name = "我是实例的属性";
}
var p = new Person();
console.log(p.propertyIsEnumerable("name")); //true
Person.prototype.sayHello = function() {
    console.log("我是原型的属性");
}
console.log(p.propertyIsEnumerable("sayHello")); //false
for (var i in p) {
console.log(i); //name,sayHello
} 

在使用for-in循环时,返回的都是所有能够通过对象访问的、可枚举的属性,其中既包括存在于实例中的属性,也包括存在于原型中的属性。(JS高程)

4)toString和toLocaleString:将对象转换成字符串

var now = new Date();
console.log(now.toString());
//Fri May 25 2018 17:39:17 GMT+0800 (中国标准时间)
console.log(now.toLocaleString());
//2018/5/25 下午5:39:41

小结:
toString()方法获取的是String(传统字符串)
而toLocaleString()方法获取的是LocaleString(本地环境字符串)
一般推荐使用toString(),它不会因为本地环境的改变而发生变化。但如果是为了返回时间类型的数据,推荐使用LocaleString()。

5)valueOf:原型对象的一个方法,获取当前对象的值。

在对象参与运算的时候,默认的会先去调用对象的valueOf方法,如果valueOf获取到的是值无法计算,就去调用p的toString方法。最终做的就是字符串拼接的工作。

关于toString和valueOf,我觉得网上的文章只有这篇写的比较详细,所以我把地址粘过来啦,有兴趣的点进去看看吧~
Javascript中的valueOf与toString

6)._ _ proto _ _:是原型中的属性,指向当前对象的原型对象。

但是它是一个非标准的属性,为了保证通用性,不推荐使用。原则就是不允许通过对象给原型添加属性,一般用于调试。

3.关键字 instanceof

用来判断该构造函数的原型是否存在于该对象的原型上。
语法:

对象 instanceof 构造函数

因为 JavaScript中所有的对象 都会有 Object.prototype
所以所有的对象 instanceof Object 都是true

猜你喜欢

转载自blog.csdn.net/cathence/article/details/80453701