1.JavaScript中每一个对象都有一个特殊的内置属性[[prototype]],这个特殊的对象可以指向另一个对象
浏览器给我们提供了一个API 可以查看这个原型对象 __proto__
我们每个对象中都有一个[[prototype]],这个属性可以称之为对象的原型(隐式原型)
2. 原型的作用
当从一个对象中获取某一个属性时,会触发[[get]]操作
// 1. 当前对象中去查找对应的属性,如果找到就直接使用
// 2. 如果没有找到,就会沿着它的原型去查找[[prototype]]
3. 函数的原型:函数因为本身它是一个函数,所以它还会多出来一个显示原型属性:prototype
通过构造函数创建出来的对象,这个对象的内部的[[prototype]]属性会被赋值为该构造函数的prototype属性
function foo() {
}
var f1 = new foo()
var f2 = new foo()
console.log(f1.__proto__ === foo.prototype) // true
console.log(f2.__proto__ === foo.prototype) // true
在内存中f1、f2对象的__proto__都指向了foo函数的显示原型对象prototype
原型链:从一个对象上获取属性,如果当前对象中没有获取到就会去它的原型上获取:
var obj = {
name: "hgf",
age: 18
}
obj.__proto__ = {
}
obj.__proto__.__proto__ = {
address: "广东省"
}
console.log(obj.address) // 广东省
4. Object的原型
obj.__proto__.__proto__的尽头 其实是 //[Object: null prototype] {}
这个原型就是我们的最顶层原型了
从Object直接创建出来的对象的原型都是[Object: null prototype] {}
[Object: null prototype] {}的特殊之处:
①该对象有原型属性__proto__ :null 指向null,也就是已经是顶层原型了;
②该对象上有很多默认的属性和方法;
Object的顶层原型来自哪里
即为Object.prototype
var obj = {
name: "hgf",
age: 18
}
console.log(obj.__proto__) // [Object: null prototype] {}
console.log(Object.prototype) // [Object: null prototype] {}
console.log(obj.__proto__ === Object.prototype) //true
会发现Object是所有类的父类
5. 原型内容的补充
对象的方法
①hasOwnProperty() // 判断是否有某一个属于自己的属性(不是在原型上的属性)
var obj = {
name: "hgf",
age: 20
}
var info = Object.create(obj, {
address: {
value: "广东省",
enumerable: true
}
})
console.log(info.hasOwnProperty("address")) // true
console.log(info.hasOwnProperty("name")) //false
②in/for in 操作符 // 判断某个属性是否在某个对象或对象的原型上
// in 操作符: 不管在当前对象还是原型中返回的都是true
console.log("address" in info)
console.log("name" in info)
// // for in
for (var key in info) {
console.log(key)
}
③instanceof // 用于检测构造函数的prototype,是否出现在某个实例对象的原型链上
function createObject(o) {
function Fn() {}
Fn.prototype = o
return new Fn()
}
// 封装的继承函数
function inheritPrototype(SubType, SuperType) {
SubType.prototype = createObject(SuperType.prototype)
Object.defineProperty(SubType.prototype, "constructor", {
enumerable: false,
configurable: true,
writable: true,
value: SubType
})
}
function Person() {
}
function Student() {
}
// 让Student继承自Person
inheritPrototype(Student, Person)
console.log(Person.prototype.__proto__)
var stu = new Student()
console.log(stu instanceof Student) // true
console.log(stu instanceof Person) // true
console.log(stu instanceof Object) // true Objcet是所有对象的父类
④isPrototypeof // 用于检测某个对象,是否出现在某个实例对象的原型链上
function Person() {
}
var p = new Person()
console.log(p instanceof Person) // true
console.log(Person.prototype.isPrototypeOf(p)) // true
//
var obj = {
name: "why",
age: 18
}
var info = Object.create(obj)
// console.log(info instanceof obj) 会报错 因为obj不是一个构造函数
console.log(obj.isPrototypeOf(info)) // true
对象-函数-原型之间的关系
函数的prototype与proto,函数本身也是一个对象(因为函数相当于 new Function()创建),之间的关系
function Foo() {
}
// Foo作为一个函数,那么它本身会有一个显示原型对象:Foo.prototype
// Foo.prototype来自哪里
// 答案:创建了一个函数,Foo.prototype = {constructor: Foo} //是Foo函数的显示原型,是一个对象
// Foo作为一个对象 因为函数相当于 new Function()创建,那么它会有一个隐式原型对象:Foo.__proto__
// Foo.__proto__来自哪里
// 答案: new Function() Foo.__proto__ = Function.prototype
// Function.prototype = {constructor: Function}
Foo.prototype === Foo.__proto__ //false
Function.prototype === Function.__proto__(Function最特殊的地方)