前言
粗略记录一下,然后让大神看看顺便纠正?
内容
- 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的继承
补充中。。。
参考链接:
挺好的原型对象说明文章
原型链说明文章
发表回复