显式原型与隐式原型
1. 每个函数function都有一个prototype,即显式原型(属性)
function Fn() { // 内部语句: this.prototype = {}
}
console.log(Fn.prototype)
2. 每个实例对象都有一个__proto__,可称为隐式原型(属性)
有两种:1)new Person() 产生 2)函数(一般不这样说)new Function产生
//创建实例对象
var fn = new Fn() // 内部语句: this.__proto__ = Fn.prototype
console.log(fn.__proto__)
3. 对象的隐式原型的值为其对应构造函数的显式原型的值
保存的都是地址值,且值是相等的,都指向原型对象
console.log(Fn.prototype===fn.__proto__) // true
4.
* 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象
* 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值
* 程序员能直接操作显式原型, 但不能直接操作隐式原型(ES6之前)
先有的显式原型
原型链
1.原型链
* 访问一个对象的属性时,
* 先在自身属性中查找,找到返回
* 如果没有, 再沿着__proto__这条链向上查找, 找到返回
* 如果最终没找到, 返回undefined
* 别名: 隐式原型链
* 作用: 查找对象的属性(方法) //查找变量看作用域链
2. 构造函数/原型/实体对象的关系
var o1 = new Object(); var o2 = { };
3. 构造函数/原型/实体对象的关系2
function Foo(){ }
var Foo = new Function()
Function = new Function()
原型链属性问题
1. 读取对象的属性值时: 会自动到原型链中查找
2. 设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值
3. 方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上
function Fn() {
}
Fn.prototype.a = 'xxx'
var fn1 = new Fn()
console.log(fn1.a, fn1) // xxx
var fn2 = new Fn()
fn2.a = 'yyy' //查找对象属性值的时才会看原型链,设置属性值时不回查找原型链,
console.log(fn1.a, fn2.a, fn2) //xxx yyy
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.setName = function (name) {
this.name = name
}
var p1 = new Person('Tom', 12)
p1.setName('Bob') //属性在对象自身,方法在原型
console.log(p1) // Person('Bob', 12)
var p2 = new Person('Jack', 12)
p2.setName('Cat')
console.log(p2) //Cat 12 //每个对象都有自己的属性
console.log(p1.__proto__===p2.__proto__) // true
p1.__proto__===p2.__proto__ 构造函数都为Person
两道测试题~~~
/*
测试题1
*/
function A () {
}
A.prototype.n = 1
var b = new A() //通过隐式原型可看到n
A.prototype = { //新的对象
n: 2,
m: 3
}
var c = new A() //新的实例
console.log(b.n, b.m, c.n, c.m) // 1 undefined 2 3
/*
测试题2
*/
function F (){}
Object.prototype.a = function(){
console.log('a()')
}
Function.prototype.b = function(){
console.log('b()')
}
var f = new F()
f.a() //a()
f.b() //报错 找不到
F.a() //a()
F.b() //b()
console.log(f) //F {} __proto__: Object
console.log(Object.prototype) //Object{。。。}
//console.log(Function.prototype)