资讯专栏INFORMATION COLUMN

几句话就能让你理解:this、闭包、原型链

LeoHsiun / 2322人阅读

摘要:也就是说这个外部函数的作用域就是闭包本身。无论通过何种手段直接或间接将内部函数传递到所在的词法作用域以外,它都会持有对原始定义作用域的引用,无论在何处执行这个函数都会使用闭包。

以下是个人对这三个老大难的总结(最近一直在学习原生JS,翻了不少书,不少文档,虽然还是新手,但我会继续坚持走我自己的路)

原型链

所有对象都是基于Object.prototypeObject.prototype就是JavaScript的根对象,在Object.prototype中定义的方法都可以被其它对象访问到,当然也可以被重写了,所以直接在Object.prototype上调用的是原始功能的toString()方法,该方法会放回参数对象的内置属性[[class]]的值,这个值是个字符串,比如"[Object String]"

要理解原型链机制的话,首先得知道根本原因:JavaScript中的对象都有一个内置属性[[Prototype]],这个属性和非标准的__proto__属性一样,__proto__在ES6中被纳入标准了,可以说它们基本上是等价的,但内置属性是无法访问到的。对象之间通过内置属性[[Prototype]]关联了起来就形成了原型链,而原型链的顶层就是根对象Object.prototypeObject.prototype的原型将是null,即Object.prototype.__proto__ === null;

例如:
在访问对象的属性的时候,如:obj.a,首先查找自身,没有,就到它的内置属性[[Prototype]]所引用的对象上找,还是没有,就继续在这个上层对象的内置属性[[Prototype]]所引用的对象上找,一直找到根对象Object.prototype,找不到就返回undefined;

this

理解this的第一步就是要明白:this既不指向函数自身,也不指向函数的词法作用域;
this是在运行时进行绑定的,而不是在编写时绑定,它的上下文取决于函数调用时的各种条件;
this的绑定和函数声明的位置没有任何关系,只取决于函数的调用位置和调用方式;
this绑定规则有4点:按优先级1到4判断

由new调用?绑定到新创建的空对象;

call、apply、bind调用?绑定到指定的参数对象;如foo.call(obj)

由上下文对象调用?绑定到这个上下文对象;如obj.foo()

默认情况下绑定到全局对象,foo();在严格模式下绑定到undefined

闭包
function foo(){
        var a = 2;
        function bar(){}
        return bar;
}
var a = foo();
a(); 

闭包:不是指函数bar也不是a,它是一个引用,这个引用被内部函数bar持有,这个引用指向外部函数foo的整个作用域,它使得这个作用域即使在外部函数foo()执行后也不会被垃圾回收器回收。也就是说这个外部函数foo的作用域就是闭包本身。
无论通过何种手段(直接或间接)将内部函数传递到所在的词法作用域以外,它都会持有对原始定义作用域的引用,无论在何处执行这个函数都会使用闭包。

var fn;  //间接传递函数
function foo(){
        var a = 2;
        function baz(){
            console.log(a);
        }
        fn = baz;
}
function bar(){ fn();}
foo();
bar();
function foo(){
        var a = 2;
        function  baz(){
            console.log(a);
        }
        bar(baz);
}
function bar(fn){ fn(); }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80487.html

相关文章

  • 继承与原型

    摘要:既然构造函数有属于自己的原型对象,那么我们应该能让另一个构造函数来继承他的原型对象咯我们在构造函数内部执行了函数并改变了函数内部的指向其实这个指向的是实例化之后的对象。 我们在讨(mian)论(shi)JavaScript这门语言时,总是绕不过的一个话题就是继承与原型链。那么继承与原型链到底是什么呢? 我很喜欢的一个聊天模式是:我不能说XX是什么,我只能说XX像什么。也就是说我不直接跟...

    My_Oh_My 评论0 收藏0
  • JavaScript系列(四) - 收藏集 - 掘金

    摘要:函数式编程前端掘金引言面向对象编程一直以来都是中的主导范式。函数式编程是一种强调减少对程序外部状态产生改变的方式。 JavaScript 函数式编程 - 前端 - 掘金引言 面向对象编程一直以来都是JavaScript中的主导范式。JavaScript作为一门多范式编程语言,然而,近几年,函数式编程越来越多得受到开发者的青睐。函数式编程是一种强调减少对程序外部状态产生改变的方式。因此,...

    cfanr 评论0 收藏0
  • JS原型,作用域,上下文,闭包this查缺补漏(大杂烩)

    摘要:走在前端的大道上本篇是一篇文章带你理解原型和原型链一篇文章带你完全理解的查漏补缺,会不断丰富提炼总结更新。 走在前端的大道上 本篇是 一篇文章带你理解原型和原型链 、一篇文章带你完全理解this的查漏补缺,会不断丰富提炼总结更新。 什么是原型链 原型链 是针对构造函数的,比如我先创建了一个函数,然后通过一个变量new了这个函数,那么这个被new出来的函数就会继承创建出来的那个函数的属性...

    eccozhou 评论0 收藏0
  • JS之原型原型

    摘要:因此,就会形成一个原型链对象到原型,再到原型的原型如果一层层地上溯,所有对象的原型最终都可以上溯到,即构造函数的属性。 对于很多前端开发者而言,JavaScript中原型与原型链是一个比较容易疑惑的点,所以本文记录了自己对应这方面的一点理解,以后有更深的理解再来更新。 对象 想要了解原型与原型链,首先要了解什么是对象?面向对象编程(Object Oriented Programmin...

    Fourierr 评论0 收藏0
  • 2018年3月面试心得《上下文,作用域》

    摘要:因为一旦代码丢出来了,还会涉及到继承,构造函数,原型链,闭包等一系列问题在后面等着你,面试管为了掏你的底细会一问再问,问到你懵逼。不可以当作构造函数,也就是说,不可以使用命令,否则会抛出一个错误。 上一篇2018年3月面试心得《跨域问题》 话说我在面试的时候,有那么几天,不知道是中了什么邪,面试的几家公司开始疯狂的问我this,各种的this,绕着弯的问我this,后来我做梦都是thi...

    zhangyucha0 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<