JS高级--原型链闭包作用域函数的四种调用方式

Posted 麋鹿不迷路Ooo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS高级--原型链闭包作用域函数的四种调用方式相关的知识,希望对你有一定的参考价值。

一、原型链(家族族谱)


 

  • 概念:JS里面的对象可能会有父对象,父对象还会有父对象,。。。。。祖先
  • 根本:继承
属性:对象中几乎都会有一个__proto__属性,指向他的父对象
意义:可以实现让该对象访问到父对象中相关属性
  • 根对象:Object.prototype
var arr=[1,3,5]
arr.__proto__:Array.prototype
arr.__proto__.__proto__就是找到了根对象
function Animal(){}
var cat=new Animal();
//cat.__proto__:Animal.prototype
//cat.__proto__.__proto__:根对象
  • 错误的理解:在js中,万物继承自Object? -->在js中万物继承自Object.prototype

二、作用域


(一)、变量作用域

 

 

  • 变量作用域的概念:就是一个变量可以使用的范围
  • JS中首先有一个最外层的作用域:称之为全局作用域
  • JS中还可以通过函数创建出一个独立的作用域,其中函数可以嵌套,所以作用域也可以嵌套
var age=18; //age是在全局作用域中声明的变量:全局变量
function f1(){
    console.log(name); //可以访问到name变量
    var name="周董" //name是f1函数内部声明的变量,所以name变量的作用域就是在f1函数内部
    console.log(name); //可以访问到name变量
    console.log(age); //age是全局作用域中声明的,所以age也可以访问
}
console.log(age); //也可以访问

 

//-->1级作用域
var gender="男";
function fn(){
    console.log(age);    //因为age是在fn作用域内声明的
    //age:undefined:既然有值就是可以访问
    console.log(height);//height不是在该作用域内部声明的,所以不能访问
    //-->2级作用域
    return function(){
        //-->3级作用域
        var height=180;
    }
    var age=5;
}

//注意:变量的声明和赋值是在两个不同时期的
function fn(){
    console.log(age);   //undeinfed
    var age=18;
    console.log(age);   //18
}

//fn函数执行的时候,首先找到函数内部所有的变量、函数声明,把他们放在作用域中,给变量一个初始值:undefined    -->变量可以访问
//逐条执行代码,在执行代码的过程中,如果有赋值语句,对变量进行赋值

function fn(){
    var age;        //初始值:undefined
    console.log(age);   //undeinfed
    age=18;     //修改了变量的值
    console.log(age);   //18
}

 

(二)、作用域链

  • 由于作用域是相对于变量而言的,而如果存在多级作用域,这个变量又来自于哪里?这个问题就需要好好地探究一下了,我们把这个变量的查找过程称之为变量的作用域链
  • 作用域链的意义:查找变量(确定变量来自于哪里,变量是否可以访问)
  • 简单来说,作用域链可以用以下几句话来概括:(或者说:确定一个变量来自于哪个作用域)
  1. 查看当前作用域,如果当前作用域声明了这个变量,就确定结果
  2. 查找当前作用域的上级作用域,也就是当前函数的上级函数,看看上级函数中有没有声明
  3. 再查找上级函数的上级函数,直到全局作用域为止
  4. 如果全局作用域中也没有,我们就认为这个变量未声明(xxx is not defined)
function fn(callback){
    var age=18;
    callback()
}

fn(function(){
    console.log(age);
    //分析:age变量:
    //1、查找当前作用域:并没有
    //2、查找上一级作用域:全局作用域
    //-->难点:看上一级作用域,不是看函数在哪里调用,而是看函数在哪里编写
    //-->因为这种特别,我们通常会把作用域说成是:词法作用域
})

举例1:

    var name="张三";
    function f1(){
        var name="abc";
        console.log(name);  //abc
    }
    f1();

举例2:

    var name="张三";
    function f1(){
        console.log(name);  //underfind
        var name="abc";
    }
    f1();

举例3:

    var name="张三";
    function f1(){
        return function(){
            console.log(name); //underfind
        }
        var name="abc";
    }
    var fn=f1();
    fn();

举例4:

    var name="张三";
    function f1(){
        return {
            say:function(){
                console.log(name);  //underfind
                var name="abc";
            }
        }
    }
    var fn=f1();
    fn.say()

 

 
 
 
 
 

以上是关于JS高级--原型链闭包作用域函数的四种调用方式的主要内容,如果未能解决你的问题,请参考以下文章

JS面试题(进阶)——原型链、this指向、闭包

js函数js对象的这些点你真的懂吗?

什么是作用域, 什么事闭包, 什么事原型链

原型模式故事链--JS变量作用域作用域链闭包

剑指offer(面试战备ing,持续更新)

剑指offer(面试战备ing,持续更新)