天天看点

原型、原型链、作用域、作用域链、闭包

相信看到题目都知道,这些都是js千年不变的面试题。

原型、原型链?

什么是原型、原型链?

原型:相当于一个模具,用来生产实例对象。

原型链:原型对象有个指针指向构造函数,实例对象又有一个指针指向原型对象,就形成了一条原型链,最终指向null。

为什么存在?

原型:就是js里实现面向对象的方式,也就是说,js就是基于原型的面向对象。

原型链:是js实现继承的方式。

作用域、作用域链?

什么是作用域、作用域链?

  • 作用域
所谓作用域,就是变量或者是函数能作用的范围。

那么JavaScript里有什么作用域呢?

1、全局作用域

除了函数中定义的变量之外,都是全局作用域。

举个栗子:

var a = ;
function bar(){
    console.log(a);
}
bar();//10
复制代码
           

以上的a就是全局变量,到处可以访问a。 然鹅,

var a = ;
function bar(){
    console.log(a);
    var a = ;
}
bar();//undefined
复制代码
           

什么鬼?undefined?

是的,你没看错。因为先搜索函数的变量看是否存在a,存在,又由于a被预解析(变量提升),提升的a绑定了这里的a作用域,所以结果就是undefined。

2、局部作用域

函数里用var声明的变量。

举个栗子:

var a = ;
function bar(){
   var a  = ;
    console.log(a);
}
bar();//20
复制代码
           

3、没有块级作用域(至ES5),ES6中有块级作用域

ES6之前,除了函数之外的块都不具备块级作用域。

常见的经典例子:

for(var i=;i<;i++){
    setTimeout(function(){
    	console.log(i);
    },);
}
//4 4 4 4
复制代码
           

解决办法:

for(var i=;i<;i++){
    (function(j){
            setTimeout(function(){
    	console.log(j);
    },);
    })(i)
}
//0 1 2 3
复制代码
           
  • 作用域链
变量随着作用长辈函数一级一级往上搜索,直到找到为止,找不到就报错,这个过程就是作用域链起的作用。
var num = ;
function f1(){
    var num  = ;
    function f2(){
        var num = ;
        function f3(){
            var num = ;
            console.log(num);
        }
        f3();
    }
   f2();
}
f1();
复制代码
           

闭包

闭包:js里为了实现数据和方法私有化的方式。内层函数可以调用外层函数的变量和方法。

经典的面试题

如果有这样的需求

  • go('l') -> gol
  • go()('l') -> gool
  • go()()('l') -> goool
var go = function (a) {
var str = 'go';
    var add0 = function (a) {
    	str += 'o';
    	return a ? str += a : add0;// 巧妙使用
    }
	return a ? str += a : add0;// 巧妙使用
}
console.log(go('l'));//gol
console.log(go()('l'));//gool
console.log(go()()('l'));//goool
复制代码
           

继续阅读