1、作用域链 -- 要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用”
如果代码中只有声明没有赋值,显示 undefined
如果既无声明也没赋值,就会报错
var a = 10;
function f1() {
var b = 20;
function f2() {
// 当前作用域没有此变量时,逐级往父作用域上面找
var c = 30;
console.log(a) // 自由变量
console.log(b) // 自由变量
console.log(c)
}
f2()
}
f1()
2、原型链
在访问对象的属性和方法时, 会在当前对象中查找, 如果没有找到, 会一直沿着原型链上的原型对象proto向上查找, 直到找到Object.prototype(原型的顶端)为止,这就是原型链。
function Dog() {
this.eat = function () {
console.log('喜欢吃骨头')
}
}
function Cat() {
this.food = function () {
console.log('喜欢吃鱼')
}
}
Cat.prototype.weight = function () {
console.log('不重')
}
Dog.prototype = new Cat();
var dog = new Dog();
dog.eat() // 喜欢吃骨头
dog.food() // 喜欢吃鱼
dog.weight() // Cat的原型对象的方法会被继承下来
3、闭包
闭包的使用场景
1、函数作为返回值
2、函数作为参数传递-----要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用
function F1() {
var a = 10; //如果这条代码消失,a会取上一级作用域的值
console.log('b')
return function () {
console.log(a) // a 为自由变量
}
}
var f1 = F1();
var a = 20;
// f1(); // 10
function F2(fn) {
var a = 30; // a不会取调用它的作用域的值
fn()
}
F2(f1) // 10
网友评论