作用域:作用域分为全局作用域和函数作用域
变量提升:变量的声明,真正的赋值是在执行代码的时候
函数提升:函数提升分为两步,第一步函数声明,第二步变量的赋值
箭头函数:箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象
this指向:
eg1:
var name = 'win'
const obj = {
name: 'obj',
a: () => {
console.log(this.name)
}
}
const obj1 = {
name: 'obj1'
}
obj.a.call(obj1)====>win ---call的调用对箭头函数无效
eg2:
var x = 11;
var obb = {
x: 222,
y: {
x:333,
obc: function f() {
console.log(this)
var x = 111;
var obj = {
x: 22,
say: () => {
console.log(this.x);
}
}
obj.say()
}
}
}
obb.y.obc() ====>333
原因:箭头函数没有this,剪头函数的this是继承父执行上下文里面的this ,这里箭头函数的执行上下文是函数f(),所以它就继承了f()的this。简单对象(非函数)是没有执行上下文的
eg3:
var x = 11;
var obb = {
x: 222,
y: {
x: 333,
obc: f = () =>{
console.log(this)
var x = 111;
var obj = {
x: 22,
say: () => {
console.log(this.x);
}
}
obj.say();
}
}
}
obb.y.obc() === >11 如果f也是一个剪头函数,它就只能继续向上找也就是window了
eg4:
var name = "dianping";
const foo = {
name: "meituan",
test() {
console.log(this.name);
},
test1: () =>{console.log(this.name)}
}
foo.test1() ---> dianping
foo.test()
eg5:
const name2 = "dianping";
const foo = {
name2: "meituan",
test() {
console.log(this.name2);
},
test1: () =>{console.log(this.name2)}
}
foo.test1() //----->undefined let和const定义的变量属于块级作用域,不会提升到全局对象window中
注:window中有个默认值为空串的name属性window.name=''
eg6:
var name = 'global'
var obj = {
name: 'obj',
method: function() {
this.name = 'local'
return function(){
return this.name
}
},
}
console.log(obj.method().call(this)) // global
eg7:
var name = 'global'
var obj = {
name: 'obj',
method: function() {
this.name = 'local'
return ()=>{
return this.name
}
},
}
console.log(obj.method().call(this)) // local ==>call的调用对箭头函数无效
eg8:
var count = 10;
function a() {
return count + 10;
}
function b() {
var count = 20;
return a(); //window.a()
}
console.log(b()); // 20 ===> a的this是window所以是10+10
eg9:
var point = {
x : 0,
y : 0,
moveTo : function(x, y) {
// 内部函数
var moveX = function(x) {
this.x = x;
};
// 内部函数
var moveY = function(y) {
this.y = y;
};
moveX(x); //全局调用 window.moveX(x)
moveY(y); //全局调用 window.moveY(y)
}
};
point.moveTo(1, 1);
console.log(point.x); // 0
console.log(point.y); // 0
eg10:
var point = {
x : 0,
y : 0,
moveTo : function(x, y) {
// 内部函数
var moveX = (x)=> {
this.x = x;
};
// 内部函数
var moveY = (y)=> {
this.y = y;
};
moveX(x); //箭头函数的this,继承”父执行上下文的this“
moveY(y);
}
};
point.moveTo(1, 1);
console.log(point.x); // 1
console.log(point.y); // 1
eg11:
function Point(x, y){
this.x = x;
this.y = y;
this.moveTo = function(x,y){
console.log(this)
// this.x = x;
// this.y = y;
console.log(this.x);
console.log(this.y);
}
}
var p1 = new Point(0,0);
// 注意这种形式方法的调用及apply、call的使用
// {x:0,y:0,moveTo:function(x,y){this.x=x,this.y=y}}
var p2 = {
x:1,
y:1
}
p1.moveTo(1,1); //0,0 指向构造函数的this
p1.moveTo.apply(p2,[10,10]); //1,1 指向构造函数的实例对象本身this
eg12:
function Point(x, y){
this.x = x;
this.y = y;
this.moveTo = (x,y)=>{
console.log(this)
// this.x = x;
// this.y = y;
console.log(this.x);
console.log(this.y);
}
}
var p1 = new Point(0,0);
// 注意这种形式方法的调用及apply、call的使用
// {x:0,y:0,moveTo:function(x,y){this.x=x,this.y=y}}
var p2 = {
x:1,
y:1
}
p1.moveTo(1,1); //0,0 指向构造函数的this
p1.moveTo.apply(p2,[10,10]); //0,0 指向构造函数的实例对象本身this,箭头函数apply不生效
作用域和变量提升:
eg1:
var a = 10
function b() {
a = 100
}
b()
console.log(a) //100 全局作用域
eg2:
var a = 10
function b() {
a = 100
return;
function a() {}
}
b()
console.log(a) //10 ===>b函数中的存在函数a的提升,在b函数作用域创建了a对象
eg3:
var a = 10
if (true) {
var a = 100
}
console.log(a) // 100 ===> if不会创建作用域
let a = 10
if (true) {
let a = 100
}
console.log(a)//10 ==> let创建了块级作用域,“{}"就是一个块级