原型与原型链
1、原型
? 函数的prototype属性,默认指向一个object空对象(原型对象),object是Function的实例对象,他的原型对象是null
? 空对象:没有我们的属性
? 原型对象的方法是给实例对象使用的
? 原型对象中有一个属性constructor,指向函数对象
Date.prototype.constructor === Date //true
? 给原型对象添加属性或者方法给实例对象使用
2、显式原型和隐式原型
每个函数function都有一个prototype,即显式原型
每个实例都有--proto--,隐式原型
对象的隐式原型的值 等于 对应构造函数的显示原型的值
所有函数的__proto__
都是一样的,都是new Function产生的
1、object是Function的实例对象,他的原型对象是null,其余函数额原型对象嗾使空的object对象
2、Function是自身的实例,所有函数都是大写Function的实例
3、Object的原型对象是原型链的尽头
既有显式原型又有隐式原型并且指向同一个地址,说明他是new自己创建的 Funtion = new Function()
function Fn(){}
var fn = new Fn()
fn.__proto__ === Fn.prototype //true
函数的prototype属性:在定义函数时自动添加,默认值是一个空object对象,空object对象的原型对象的proto是null,是原型链的最底层。object.prototype.__proto__=null
实例对象的--proto--属性:实例对象创建时将prototype赋值给--proto--
注意:我们可以操作函数的显式原型,但是不能直接操作对象的隐式原型(ES6之前)
3、原型链(隐式原型连)
访问一个对象的属性时:
自身属性-->--proto__ -->undifined
属性都放在对象身上,但是方法放在原型上
执行上下文与执行上下文栈
1、变量提升与函数提升
var a = 3;
function fn(){
console.log(a)
var a = 4
}
//undefined 变量提升:var定义,在之前就可以访问到,但是是undefined
function fn2(){} //之只能这样定义
//函数提升:通过function声明的函数对象,在之前就可以调用,并且就是定义的function
2、执行上下文
2.1、全局执行上下文:
? 执行代码前将window确定为全局执行上下文
? 对全局数据进行预处理
? var的变量定为undefined,添加为执行上下文属性
? function声明的函数,添加为window方法
? 将this赋值window
? 开始执行全局代码
2.2、函数执行上下文
在调用函数,准备执行函数之前,创建对应的函数执行上下文
对局部数据进行预处理
? 形参变量==>赋值(实参)-->添加为执行上下文属性
? arguments==>赋值(实参列表),添加为执行上下文属性
? var的变量定为undefined,添加为执行上下文属性
? function声明的函数,添加为window方法
? this==>赋值(调用函数的对象)
开始执行函数体代码
3、执行上下文栈
? 调用一次函数执行一次上下文对象,最开始产生一个window上下文对象
在全局代码执行前,js引擎会创建一个栈来存储管理所有的执行上下文对象
在全局执行上下文(window)确定后,将其添加到栈中(压栈)
在函数执行上下文创建后,将其添加到栈中(压栈)
在当前函数执行完后,将栈顶的对象移除(出栈)
当所有的代码执行完后,栈中只剩下window
面试题:
function a(){}
var a
console.log(typeof a) //function
//先执行变量提升,在执行函数提升
function a(){}
var a =1
console.log(typeof a) //number
var c = 1
function c(c){
console.log(c)
}
c(2)
//执行结果 报错 c is not a function
相当于
var c
function c(c){
console.log(c)
}
c = 1
c(2)