
构造函数:function Foo ( ) { };实例对象:let f1 = new Foo();1. 谈到继承时,JavaScript 只有一种结构:对象2. 每个函数都有 prototype 属性,除了 Function.prototype.bind(),该属性指向原型。3. 凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。
prototype
每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型对象,每一个对象都会从原型”继承”属性。
每个对象都有 proto 属性,但只有函数对象才有 prototype 属性
proto
每一个JavaScript对象(除了 null )都具有的一个属性,叫proto,这个属性会指向了创建该对象的构造函数的原型。
console.log(f1._proto_ === Foo.prototype) // true
constructor
每个原型都有一个 constructor 属性指向关联的构造函数
由于实例对象可以继承原型对象的属性,所以实例对象也拥有constructor属性,同样指向原型对象对应的构造函数。
console.log(Foo.prototype.constructor === Foo);//true
console.log(f1.constructor === Foo);//true
console.log(f1.hasOwnProperty('constructor'));//false
原型链
JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做**proto**的内置属性,用于指向创建它的函数对象的原型对象prototype。以上面的例子为例:
console.log(f1.__proto__ === Foo.prototype) //true
同样Foo.prototype也有proto属性
console.log(Foo.prototype.__proto__ === Object.prototype) //true
Object.prototype对象也有proto属性,但它比较特殊,为null
console.log(Object.prototype.__proto__ === null)
我们把这个有proto串起来的直到Object.prototype.proto为null的链叫做原型链。原型链的形成是真正是靠proto 而非prototype
总结
每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为: 原型对象)
原型对象都包含一个属性constructor,是一个指针,指向构造函数本身
实例对象包含一个属性proto,是一个指针,指向该构造函数的原型
作用域和作用域链
(1) 作用域
- 程序代码中定义变量的区域,简单说就是变量的可访问范围,在该区域中控制着变量的可见性。
它是静态的(相对于上下文对象), 在编写代码时就确定了
(2) 作用域链
理解
- 多个上下级关系的作用域形成的链, 它的方向是从内到外
- 查找变量时就是沿着作用域链来查找的
作用域链保证了当前执行上下文对符合访问权限的变量的有序访问。
- 查找一个变量的查找规则
- 在当前作用域下的执行上下文中查找对应的属性, 如果有直接返回, 否则进入2
- 在上一级作用域的执行上下文中查找对应的属性, 如果有直接返回, 否则进入3
- 再次执行2的相同操作, 直到全局作用域, 如果还找不到就抛出找不到的异常
