重新整理的一遍JS的原型链继承

前言

粗略记录一下,然后让大神看看顺便纠正?

内容

  • JS的原型链相关
  • JS继承(正在看中)

JS的原型链相关

一、首先,JS里几乎所有值都是对象(使用的时候)!

我们知道,JS基础数据类型是 number,string,boolean,undefined和null,而引用类型就object,
之前看的时候,我很奇怪为什么像var str = “”;这个str明明的类型是String,为什么它却可以引用String.prototype原型对象的属性和方法呢,并且它确实有对象才有的__proto__和constructor属性,

var str = '';      

console.log(str.__proto__ === String.prototype) //true

console.log(str.constructor === String) //true

console.log(str instanceof String); //false,前面两个都符合了,这个竟然是返回false,不是String的实例

console.log(String.prototype.isPrototypeOf(str)); //false,跟instanceof功能是一样的

后面百度查了一下,原因是

读取字符串的时候会创建一个对象,但是这个对象只是临时的,所以我们称它为临时对象,学术名字叫包装对象,说它临时,是因为我们在读取它的属性的时候,js会把这个string字符串通过new String()方式创建一个字符串对象,一旦引用结束,这个对象就被销毁了。

所以说就是像读取对象那样读取属性的时候,暗地里帮我new String()了,不读取的时候,就是基础类型,所以判断是不是实例才返回了false

str.name = 'nihao';  //可以这样写不报错,因为暗地里帮我对象化了,
str.name         //可以点name出来,但是是undefined,没错

总结:目前发现除了undefined和null不能这样搞,其他类型都是有__proto__和constructor属性,所以说,JS几乎所有值都为对象

二、__proto__,prototype,和constructor关系

首先,要明确两点的是

  • 函数才有prototype属性,这个属性指向的那个对象我们一般也叫做原型对象
  • 对象才有__proto__和constructor属性,那函数有没有?肯定有啊,函数本来就是属于引用数据类型的一种,就是Object

    • __proto__属性,指向构造函数的原型对象,也就是函数.prototype
    • constructor属性,指向构造函数,但是有一个值的constructor是特殊的,就是 函数.prototype.constructor,原型对象的constructor属性指回构造函数(?????又说特殊,不是还是指回构造函数吗,嗯,我下面会做解释)

好了,那明确这两点之后,再说说这三者有什么关系,先放图吧


先说一下这个,按照这个图的意思,有一个构造Person函数,这个函数默认就会有prototype属性,这个属性指向的值是一个对象,我们叫做原型对象,然后呢,Person.prototype这个原型对象,是的,它是一个对象,所以,它也就有constructor属性(我上面的结论),这个属性默认指回构造函数,也就是Person函数,原型对象的name,age这些就是我们自己往这个对象加的,Person.prototype.name = ‘xxx’,就像这样,然后
两个实例,person1,person2这两个对象,有__proto__属性对吧,它指向是构造函数的原型对象,就是Person.prototype

//构造函数Person
function Person(){}
//往原型对象加值
Person.prototype.name = 'mychirs';
Person.prototype.age = 29;
Person.prototype.job = 'Software Engineer';
Person.prototype.sayName = function(){
  alert(this.name);
};

//两个实例
var person1 = new Person();
var person2 = new Person();

console.log(Person.prototype.constructor === Person)  //true
console.log(person1.__proto__ === Person.prototype)  //true
console.log(person2.__proto__ === Person.prototype)  //true

好了,说完上面那个图已经差不多了,再放多一张图

这个图补充了几个上面那张图没有的点,第一,原型链的尽头是Object.prototype.__proto__,值为null;第二,函数的constructor指向的是Function这个构造函数(这个Function是JS内置的几个构造函数之一),然后Function的constructor还是指它自己,也就是Function,如果你一直.constructor.constructor,你会发现一直都是在指Function注意这里的constructor和原型对象的constructor不同,如果按照constructor指向的是构造函数,那么函数.prototype.constructor应该指向的是Object构造函数,但事实就是不是的,原型对象的constructor指的就是原型对象的构造函数,这里就证明我上面结论说的第二点,放下代码看看

//构造函数Person
function Person(){}

var obj = {}
var person1 = new Person()

console.log(Person.constructor === Function)  //true,正常来说,constructor指向的就是构造函数
console.log(Person.constructor.constructor.constructor  === Function)  //true,一直点下去都是这样

console.log(Person.prototype.constructor === Object)  //false, 原型对象的constructor是特殊的,记住就好
console.log(Person.prototype.constructor === Person)  //true,这样才对
console.log(obj.constructor === Object)  //true
console.log(person1 .constructor === Person)  //true

console.log(obj.constructor.prototype.__proto__=== null)  //true,原型链尽头,null

JS的继承

补充中。。。

参考链接:
挺好的原型对象说明文章
原型链说明文章

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理