JS引用类型四个规则

  1. 都会有一个对象特性,可以自由扩展对象
  2. 都会有一给隐式原型**proto**,该属性值是一给普通对象
  3. 隐式原型**proto属性会指向他构造函数的显示原型prototype**值
  4. 当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 proto(也就是它的构造函数的显式原型 prototype)中寻找。

引用类型:Object、Array、Function、Date、RegExp。这里我姑且称 proto 为隐式原型,没有官方中文叫法,大家都瞎叫居多。

function Star(name,age) {
    //实例成员
    this.name = name;
    this.age = age;
}
//静态成员
Star.sex = '女';

let stars = new Star('小红',18);
console.log(stars);      // Star {name: "小红", age: 18}
console.log(stars.sex);  // undefined     实例无法访问sex属性

console.log(Star.name); //Star     通过构造函数无法直接访问实例成员
console.log(Star.sex);  //女       通过构造函数可直接访问静态成员

上面的代码我们创建了一个构造函数Star,并且实例化了Stars对象,每个对象 上面都会有一给__proto__属性,并且这个属性和它构造函数上的显示原型是一样,比如stars.__proto===Star.prototype//true 原型的作用就是可以共享方法

function Star(name,age) {
    //实例成员
    this.name = name;
    this.age = age;
}
Star.prototype.sun=function(){
    console.log("this");
}
Star.prototype.dance = function(){
    console.log('我在跳舞',this.name);
};
//静态成员
Star.sex = '女';

let stars = new Star('小红',18);
console.log(stars);      // Star {name: "小红", age: 18}
console.log(stars.sex);  // undefined     实例无法访问sex属性
stars.dance()
console.log(Star.name); //Star     通过构造函数无法直接访问实例成员
console.log(Star.sex);  //女       通过构造函数可直接访问静态成员

原型链

JavaScript中的对象,都有一个内置属性[[Prototype]],指向这个对象的原型对象。当查找一个属性或方法时,如果在当前对象中找不到定义,会继续在当前对象的原型对象中查找;如果原型对象中依然没有找到,会继续在原型对象的原型中查找(原型也是对象,也有它自己的原型);如此继续,直到找到为止,或者查找到最顶层的原型对象中也没有找到,就结束查找,返回undefined。可以看出,这个查找过程是一个链式的查找,每个对象都有一个到它自身原型对象的链接,这些链接组件的整个链条就是原型链。拥有相同原型的多个对象,他们的共同特征正是通过这种查找模式体现出来的。
在上面的查找过程,我们提到了最顶层的原型对象,这个对象就是Object.prototype,这个对象中保存了最常用的方法,如toString、valueOf、hasOwnProperty等,因此我们才能在任何对象中使用这些方法。

Q.E.D.