普通对象与函数对象
普通对象普通的对象:只有__proto__属性(指向其原型链),没有prototype属性。
Object 、Function 是 JS 自带的函数对象。凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。
函数对象有__proto__及,每个函数函数对象都会有一个默认的prototype属性(指向原型对象)。
Function、Object、Array、Date、String、自定义函数
特例: Function.prototype(是原型对象,却是函数对象)
console.log(Array) //ƒ Array() { [native code] }
console.log(Array.__proto__ === Function.prototype) //true
console.log(Array.__proto__) //ƒ () { [native code] }
Array是函数对象,是Function的实例对象,Array是通过newFunction创建出来的。因为Array是Function的实例,所以Array.__proto__ === Function.prototype
__proto__ 指向谁?
__proto__指向 取决于创建对象时的实现方式
prototype与__proto__的区别:
每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性
var obj = {}
console.log(obj.__proto__)// Object {}
console.log(obj.prototype)//undefined
function Person() {
}
console.log(Person.__proto__) //function () {}
console.log(Person.prototype) //Object {}原型
1)构造函数中有一个属性:prototype,叫原型,是给我们程序员用的。
2)实例对象中有一个属性:__proto__,也叫原型,这个是给浏览器看的。
3)构造函数中的prototype和实例中的__proto__指向相同。
4)prototype的数据可以被实例对象访问和使用。
构造函数 Person
实例化对象 person1
原型对象 Person.prototype
实例是通过构造函数创建的。实例一创造出来就具有constructor属性(指向构造函数)和proto属性(指向原型对象),
构造函数中有一个prototype属性,这个属性是一个指针,指向它的原型对象。
原型对象内部也有一个指针(constructor属性)指向构造函数:Person.prototype.constructor === Person;
function Person(name) {
this.name = name;
}
var person1 = new Person("nwd")
console.log(person1.constructor)
console.log(person1.constructor === Person) // true
console.log(Person.prototype.constructor === Person) // true
console如下

function Person(name) {
this.name = name;
}
var person1 = new Person("nwd")
console.log(Person.prototype.constructor)
console.log(Person === Person.prototype.constructor ) //true
console如下

function Person(name) {
this.name = name;
}
var person1 = new Person("nwd")
console.log(person1.__proto__)
console.log(Person.prototype)
console.log(person1.__proto__ === Person.prototype) //true
console如下

注:构造函数 Person 的prototype,也是构造函数实例出来的对象person1的原型(它其实也是一个对象)
function Person(name) {
this.name = name;
}
var person1 = new Person("nwd")
console.log(person1.constructor)
console.log(person1.__proto__.constructor)
console.log(person1.constructor === person1.__proto__.constructor) //true
console如下

原型链
每个实例对象(object)都有一个私有属性(称之为__proto__)指向它的原型对象(prototype)。该原型对象也有自己的原型对象,就这样组成了原型链.
__proto__是所有对象(包括函数)都有的,它叫做对象的原型,原型链就是靠它形成的。而__proto__的终点值时null。在查找对象属性时,先确定对象是否存在该对象,不存在会在原型链上查找,不会在自身的prototype上查找。
person1具有__proto__属性,指向Person.prototypePerson.prototype具有__proto__属性,指向Object.prototypeObject.prototype具有__proto__属性,指向nullconsole.log(person1.__proto__ === Person.prototype) // true
console.log(Person.prototype.__proto__ === Object.prototype) // true
console.log(Object.prototype.__proto__) // null
这些__proto__串起来,就构成了原型链,原型链的顶端为null。
function Person() {
}
console.log(Person.__proto__)
console.log(Person.prototype)
console.log(Person.prototype.__proto__)
console.log(Object.prototype)
console.log(Object.prototype.__proto__)
注:通过__ proto __形成原型链而非protrotype
原型链是实现继承的主要方法:
function Person(sex) {
this.sex = sex;
}
Person.prototype.getSex = function() {
console.log(this.sex)
}
function Student(name) {
this.name = name
}
Student.prototype = new Person("男")
Student.prototype.say = function() {
console.log(this.name)
}
var person1 = new Student("lihe")
console.log(person1)
如下图

原型链关系如下:
console.log(person1.__proto__ === Student.prototype) //true
console.log(person1.__proto__)
console.log(Student.prototype)
console.log(Student)
console.log(Student.prototype.__proto__ === Person.prototype) //true
console.log(Student.prototype.__proto__)
console.log(Person.prototype)
console.log(Person.prototype.__proto__ === Object.prototype) //true
console.log(Person.prototype.__proto__)
console.log(Object.prototype.__proto__ === null) //true