this
词法作用域 和 动态作用域
词法作用域(静态作用域): 变量定义在哪就在哪,和函数的调用无关。动态作用域: 函数执行时决定变量作用域
let name = "小丽"
function getName ( ) {
console. log ( this . name)
}
function changeIt ( ) {
let name = "老王"
getName ( )
}
changeIt ( )
作用域链
var scope = "global scope" ;
function checkscope ( ) {
var scope = "local scope" ;
function f ( ) {
return scope;
}
return f ( ) ;
}
checkscope ( ) ;
执行上下文
js引擎分析和执行代码是一段一段的,当执行一个函数时,会有一个准备阶段(即提供代码运行的环境),这个就叫执行上下文。
顺序执行
var foo = function ( ) {
console. log ( 'foo1' ) ;
}
foo ( ) ;
var foo = function ( ) {
console. log ( 'foo2' ) ;
}
foo ( ) ;
变量、函数提升
console. log ( add2 ( 1 , 1 ) ) ;
function add2 ( a, b ) {
return a+ b;
}
console. log ( add1 ( 1 , 1 ) ) ;
var add1 = function ( a, b ) {
return a+ b;
}
this指向
直接调用函数。 隐式调用。 Class 和 new 显式改变this指向call(arg,a,b,c)/applay(arg,[a,b,c])/bind(arg)()
直接调用函数-----this指向window
function sun ( ) {
console. log ( this )
}
sun ( )
隐式绑定 ---- 直接指向调用函数的上一级
function thisFun ( ) {
console. log ( this . a)
}
const obj = {
a : "nnn" ,
fn : thisFun
}
obj. fn ( )
Class和new ---- 指向生成的实例
function NewObj ( ) {
this . a = "ddd" ;
this . b = "kkk"
console. log ( this , "this" )
}
let obj = new NewObj ( )
console. log ( obj)
显式改变this
call(arg, a, b, c) applay(arg, [a,b,c]) bind(arg)()
实现一个applay
Function . prototype. newApplay = function ( content ) {
if ( typeof this !== "function" ) {
new TypeErro ( "不是一个函数" )
}
content = content || window
content. fn = this ;
let result = arguments[ 1 ] ? content. fn ( ... arguments[ 1 ] ) : content. fn ( )
delete content. fn
return result
}
实现一个bind
Function . prototype. newBind = function ( ) {
if ( typeof this !== "function" ) {
new TypeErro ( "不是一个函数" )
}
let _this = this ;
let list = Array . prototype. slice . call ( arguments)
let newThis = list. shift ( )
return function ( ) {
_this. newApplay ( newThis, list)
}
}