变量和常量
js中使用const声明一个常量
const PI = 3.14
使用var 和 let声明变量
var a = 1;
let b = 2;
那么使用let和var声明变量有什么区别呢?
- let可以定义块级作用域变量
- let没有变量提升
- let声明的变量不能重复声明
js中的this
先来看一个对象中的一个方法:
var xiaoming = {
name: '小明',
birth: 1996,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
xiaoming.age(); // 25
在一个方法内部,this是一个特殊变量,它始终指向当前对象。现在我们将上边的方法单独拎出来,作为一个函数。
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1996,
age: getAge()
};
xiaoming.age; // NaN
纳尼?发生了什么?分析帝分析一波:
首先调用一个函数,只是获取这个函数的返回值,函数体内部的实现并不能在调用的地方体现。所以,在xiaoming这个对象调用getAge()的方法的时候,getAge()方法里面的this并不是指向xiaoming这个对象,而是全局window。所以运行结果并不能获取我们想要的。js为了让这个误区显露出来,严格模式下运行,会直接提示一个错误。
'use strict';
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1996,
age: getAge()
};
xiaoming.age; // Uncaught TypeError: Cannot read property 'birth' of undefined
严格模式下,全局函数中的this指向了undefined,不使用严格模式,则会指向window
讲函数的时候,我们提到,如果不加() ,我们会获取这个函数的函数体。如果不加(),可不可以得到我们想要的结果呢?
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1996,
age: getAge
};
xiaoming.age(); // 25
事实证明可以。
但是如果,这个函数是对象内部方法之中定义的呢,会发生什么?
'use strict'
var xiaoming = {
name: '小明',
birth: 1996,
age: function() {
return getAge();
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
}
};
xiaoming.age(); // Uncaught TypeError: Cannot read property 'birth' of undefined
无情报错。
有没有解决办法呢?我们尝试用别的变量代替this。
var xiaoming = {
name: '小明',
birth: 1996,
age: function() {
var that = this;
return getAge();
function getAge() {
var y = new Date().getFullYear();
return y - that.birth;
}
}
};
xiaoming.age(); // 25
我们用that先获取this,这个节点this指向的是xiaoming对象,所以避免了在函数内部this指向错误的问题。
还有没有别的办法呢?我们使用函数本身的apply方法修复this的指向。
'use strict'
var xiaoming = {
name: '小明',
birth: 1996,
age: function() {
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
return getAge.apply(xiaoming, []);
}
};
xiaoming.age(); // 25
apply方法接收两个参数,第一个参数就是需要绑定的this变量(设置为null则为全局),第二个参数是Array,表示函数本身的参数。我们还可以用apply实现系统函数的重写。
'use strict';
var count = 0;
var oldParseInt = parseInt; // 保存原函数
window.parseInt = function () {
count += 1;
return oldParseInt.apply(null, arguments); // 调用原函数
};
除了使用apply方法,有没有别的方法修复this的指向问题呢。有的:箭头函数。
箭头函数
箭头函数相当于简写的匿名函数。
// 单参数
x => x * x
// 多参数
(x, y) => x * x + y * y
// 空参数
() => new Date().getFullYear()
// 因为花括号在js中的特殊性,返回对象需要用()包起来
x => ({ foo: x })
// 将箭头函数赋值给变量
var func = (x, y) => x * x + y * y
箭头函数中的this总是指向词法作用域,解决了this的指向问题。
var xiaoming = {
birth: 1996,
age: function () {
var b = this.birth; // 1990
var getAge = () => new Date().getFullYear() - this.birth; // this指向xiaoming 对象
return getAge ();
}
};
xiaoming .age(); // 25