资讯专栏INFORMATION COLUMN

深入认知 JavaScript

malakashi / 2509人阅读

摘要:深入认知前言关于,平时我们仅仅做到了使用,但是真的理解为什么这么使用吗这里详细介绍一些我们常用的语法。在以下,是没有块级作用域的,只有函数作用域。而如果在作用域中嵌套作用域,那么就会有作用域链。

本文当时写在本地,发现换电脑很不是方便,在这里记录下。

深入认知 Javascript 前言

关于 Javascript,平时我们仅仅做到了使用,但是真的理解为什么这么使用吗?

这里详细介绍一些我们常用的 Javascript 语法。

关键字
what: 在Javascript 关键字是有很多的,而普通的关键字基本没有太多的难度,例如var,eval,void,break...,这里仅仅挑选两个 this 和 new 也是最让人疑惑的关键字。
1.1 this
在 Javascript6.0 以下,Javascript是没有块级作用域的,只有函数作用域。而如果在作用域中嵌套作用域,那么就会有作用域链。
foo = "window";
function first(){
    var foo = "first";
    function second(){
       var foo = "second";
       console.log(foo);
    }
    function third(){
       console.log(foo);
    }
    second(); //second
    third();  //first
}
first();

理解:当执行second时,JS引擎会将second的作用域放置链表的头部,其次是first的作用域,最后是window对象,于是会形成如下作用域链:second->first->window, 此时,JS引擎沿着该作用域链查找变量foo, 查到的是 second。当执行third时,third形成的作用域链:third->first->window, 因此查到的是:frist。

弄清楚作用域,我们在来看 this 关键字,Javascript 中的 this 总是指向当前函数的所有者对象,this总是在运行时才能确定其具体的指向, 也才能知道它的调用对象

window.name = "window";
function f(){
    console.log(this.name);
}
f();//window
 
var obj = {name:"obj"};
f.call(obj); //obj

理解:在执行f()时,此时f()的调用者是window对象,因此输出 window ,f.call(obj) 是把f()放在obj对象上执行,相当于obj.f(),此时f 中的this就是obj,所以输出的是 obj

Demo 1

var foo = "window";
var obj = {
    foo : "obj",
    getFoo : function() {
        return function() {
            return this.foo;
        };
    }
};
var f = obj.getFoo();
f();

Demo 2

var foo = "window";
var obj = {
    foo : "obj",
    getFoo : function() {
        var that = this;
        return function(){
            return that.foo;
        };
    }
};
var f = obj.getFoo();
f();

❓ Demo1 和 Demo2 的返回值是多少

代码解析:

// demo1:
//执行var  f = obj.getFoo()返回的是一个匿名函数,相当于:
var f = function(){
     return this.foo;
}
// f() 相当于window.f(), 因此f中的this指向的是window对象,this.foo相当于window.foo, 所以f()返回"window"
 
// demo2:
// 执行var f = obj.getFoo() 同样返回匿名函数,即:
var f = function(){
     return that.foo;
}
// 唯一不同的是f中的this变成了that, 要知道that是哪个对象之前,先确定f的作用域链:f->getFoo->window 并在该链条上查找that,
// 此时可以发现that指代的是getFoo中的this, getFoo中的this指向其运行时的调用者,
// 从var f = obj.getFoo() 可知此时this指向的是obj对象,因此that.foo 就相当于obj.foo,所以f()返回 "obj"
1.2 new
what: 和其他高级语言一样 Javascript 中也有 new 运算符,我们知道 new 运算符是用来实例化一个类,从而在内存中分配一个实例对象。 但在 Javascript 中,万物皆对象,为什么还要通过 new 来产生对象
1.2.1 认识

先看一个例子

01 function Animal(name){
02     this.name = name;
03 }
04 Animal.color = "black";
05 Animal.prototype.say = function(){
06       console.log("I"m " + this.name);
07 };
08 var cat = new Animal("cat");
09
10 console.log(
11     cat.name,  //cat
12       cat.height //undefined
13 );
14 cat.say(); //I"m cat
15
16 console.log(
17       Animal.name, //Animal
18       Animal.color //back
19 );
20 Animal.say(); //Animal.say is not a function

代码解析:

1-3行创建了一个函数 Animal,并在其 this 上定义了属性 name,name的值是函数被执行时的形参。

4行在 Animal 对象(Animal 本身是一个函数对象)上定义了一个静态属性 color,并赋值“black”

5-7行在 Animal 函数的原型对象 prototype 上定义了一个 say 方法,say 方法输出了 this.name

8行通过 new 关键字创建了一个新对象 cat

10-14行 cat 对象尝试访问 namecolor 属性,并调用 say 方法。

16-20行 Animal 对象尝试访问 namecolor 属性,并调用 say 方法。

重点解析:

注意到第 8 行,

var cat = new Animal("cat");

JS引擎执行这句代码时,在内部做了很多工作,用伪代码模拟其工作流程如下:

new Animal("cat") = {
    var obj = {};
    obj.__proto__ = Animal.prototype;
    var result = Animal.call(obj, "cat");
    return typeof result === "object"? result : obj;
}

代码解析:

创建一个空对象obj;

obj__proto__ 指向 Animal 的原型对象 prototype,此时便建立了 obj 对象的原型链:

obj Animal.prototype Object.prototype null

简单解释下原型对象和原型链:

原型对象:指给后台函数继承的父对象

原型链:链接成 java 的继承

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

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

相关文章

  • JavaScript基础——深入学习async/await

    摘要:等待的基本语法该关键字的的意思就是让编译器等待并返回结果。这里并不会占用资源,因为引擎可以同时执行其他任务其他脚本或处理事件。接下来,我们写一个火箭发射场景的小例子不是真的发射火箭 本文由云+社区发表 本篇文章,小编将和大家一起学习异步编程的未来——async/await,它会打破你对上篇文章Promise的认知,竟然异步代码还能这么写! 但是别太得意,你需要深入理解Promise后,...

    张金宝 评论0 收藏0
  • 某熊的技术之路指北 ☯

    某熊的技术之路指北 ☯ 当我们站在技术之路的原点,未来可能充满了迷茫,也存在着很多不同的可能;我们可能成为 Web/(大)前端/终端工程师、服务端架构工程师、测试/运维/安全工程师等质量保障、可用性保障相关的工程师、大数据/云计算/虚拟化工程师、算法工程师、产品经理等等某个或者某几个角色。某熊的技术之路系列文章/书籍/视频/代码即是笔者蹒跚行进于这条路上的点滴印记,包含了笔者作为程序员的技术视野、...

    shadowbook 评论0 收藏0
  • Node.js 是什么?我为什么选择它?

    摘要:单线程使用单线程来运行,而不是向之类的其它服务器,每个请求将生产一个线程,这种方法避免了上下文切换和内存中的大量执行堆栈,这也是和其它服务器为解决上一个年,著名的并发连接问题而采用的方法。 showImg(https://segmentfault.com/img/remote/1460000019968794?w=1080&h=675);当我们学习一项新的事物的时候,我们首先要知道它来...

    Joyven 评论0 收藏0
  • 从小白程序员一路晋升为大厂高级技术专家我看过哪些书籍?(建议收藏)

    摘要:大家好,我是冰河有句话叫做投资啥都不如投资自己的回报率高。马上就十一国庆假期了,给小伙伴们分享下,从小白程序员到大厂高级技术专家我看过哪些技术类书籍。 大家好,我是...

    sf_wangchong 评论0 收藏0

发表评论

0条评论

malakashi

|高级讲师

TA的文章

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