1.基本类型不是对象(boolean、undefined、number、string) 2.引用类型都是对象(Array,function ,Object) 3.对象是通过函数创建,并且强调,对象字面量也是通过函数创建,举例说明,ES6继承的语法糖 4.函数有的是显式原型prototype 5.对象有的是隐式原型__proto__ 和构造器 constructor 6.但是由于JS中函数也是一种对象,所以函数也拥有__proto__和constructor 7.__proto__ 属性,它是对象所独有的,可以看到__proto__属性都是由一个对象指向一个对象. 它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存在这个属性,则继续往父对象的__proto__属性所指向的那个对象(可以理解为爷爷对象)里找,如果还没找到,则继续往上找…直到原型链顶端null(可以理解为原始人。。。),再往上找就相当于在null上取值,会报错(可以理解为,再往上就已经不是“人”的范畴了,找不到了,到此结束。 8.prototype属性,它是函数所独有的,它是从一个函数指向一个对象。它的含义是函数的原型对象,也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象,它的作用就是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法。任何函数在创建的时候,其实会默认同时创建该函数的prototype对象。 8.constructor属性也是对象才拥有的,它是从一个对象指向一个函数,含义就是指向该对象的构造函数,每个对象都有构造函数(本身拥有或继承而来,继承而来的要结合__proto__属性查看会更清楚点 举栗: class Person { constructor(name) { this.name = name; } } var xiaoming = new Person('张三'); console.log(xiaoming); 输出结果: Person {name: "张三"} name: "张三" __proto__: Object __proto__就是由xiaoming(实例对象)指向Person 对象。 举栗: console.log(xiaoming.__proto__); 输出结果: {constructor: ƒ} constructor: ƒ Person(name) arguments: (...) caller: (...) length: 1 name: "Person" prototype: {constructor: ƒ} __proto__: ƒ () [[FunctionLocation]]: index.vue?0dbc:133 [[Scopes]]: Scopes[3] __proto__: Object 里面的构造器指向的是Person里面的构造函数,因为是函数,所以有prototype(显式原型) 举栗: console.log(xiaoming.__proto__.__proto__); 输出的是: {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …} constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() get __proto__: ƒ __proto__() set __proto__: ƒ __proto__() 寻找构造函数的原型,因为函数也是一个引用类型,所以构造函数指向Object对象 举栗: console.log(xiaoming.__proto__.__proto__.__proto__); 已无隐式原型,内存地址指向空对象指针,输出null