资讯专栏INFORMATION COLUMN

深入认知 JavaScript

malakashi / 2682人阅读

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

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

深入认知 Javascript 前言

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

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

关键字

</>复制代码

  1. what: 在Javascript 关键字是有很多的,而普通的关键字基本没有太多的难度,例如varevalvoidbreak...,这里仅仅挑选两个 thisnew 也是最让人疑惑的关键字。
1.1 this

</>复制代码

  1. Javascript6.0 以下,Javascript是没有块级作用域的,只有函数作用域。而如果在作用域中嵌套作用域,那么就会有作用域链。

</>复制代码

  1. foo = "window";
  2. function first(){
  3. var foo = "first";
  4. function second(){
  5. var foo = "second";
  6. console.log(foo);
  7. }
  8. function third(){
  9. console.log(foo);
  10. }
  11. second(); //second
  12. third(); //first
  13. }
  14. first();

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

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

</>复制代码

  1. window.name = "window";
  2. function f(){
  3. console.log(this.name);
  4. }
  5. f();//window
  6. var obj = {name:"obj"};
  7. f.call(obj); //obj

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

Demo 1

</>复制代码

  1. var foo = "window";
  2. var obj = {
  3. foo : "obj",
  4. getFoo : function() {
  5. return function() {
  6. return this.foo;
  7. };
  8. }
  9. };
  10. var f = obj.getFoo();
  11. f();

Demo 2

</>复制代码

  1. var foo = "window";
  2. var obj = {
  3. foo : "obj",
  4. getFoo : function() {
  5. var that = this;
  6. return function(){
  7. return that.foo;
  8. };
  9. }
  10. };
  11. var f = obj.getFoo();
  12. f();

❓ Demo1 和 Demo2 的返回值是多少

代码解析:

</>复制代码

  1. // demo1:
  2. //执行var f = obj.getFoo()返回的是一个匿名函数,相当于:
  3. var f = function(){
  4. return this.foo;
  5. }
  6. // f() 相当于window.f(), 因此f中的this指向的是window对象,this.foo相当于window.foo, 所以f()返回"window"
  7. // demo2:
  8. // 执行var f = obj.getFoo() 同样返回匿名函数,即:
  9. var f = function(){
  10. return that.foo;
  11. }
  12. // 唯一不同的是f中的this变成了that, 要知道that是哪个对象之前,先确定f的作用域链:f->getFoo->window 并在该链条上查找that,
  13. // 此时可以发现that指代的是getFoo中的this, getFoo中的this指向其运行时的调用者,
  14. // 从var f = obj.getFoo() 可知此时this指向的是obj对象,因此that.foo 就相当于obj.foo,所以f()返回 "obj"
1.2 new

</>复制代码

  1. what: 和其他高级语言一样 Javascript 中也有 new 运算符,我们知道 new 运算符是用来实例化一个类,从而在内存中分配一个实例对象。 但在 Javascript 中,万物皆对象,为什么还要通过 new 来产生对象
1.2.1 认识

先看一个例子

</>复制代码

  1. 01 function Animal(name){
  2. 02 this.name = name;
  3. 03 }
  4. 04 Animal.color = "black";
  5. 05 Animal.prototype.say = function(){
  6. 06 console.log("I"m " + this.name);
  7. 07 };
  8. 08 var cat = new Animal("cat");
  9. 09
  10. 10 console.log(
  11. 11 cat.name, //cat
  12. 12 cat.height //undefined
  13. 13 );
  14. 14 cat.say(); //I"m cat
  15. 15
  16. 16 console.log(
  17. 17 Animal.name, //Animal
  18. 18 Animal.color //back
  19. 19 );
  20. 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 行,

</>复制代码

  1. var cat = new Animal("cat");

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

</>复制代码

  1. new Animal("cat") = {
  2. var obj = {};
  3. obj.__proto__ = Animal.prototype;
  4. var result = Animal.call(obj, "cat");
  5. return typeof result === "object"? result : obj;
  6. }

代码解析:

创建一个空对象obj;

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

obj Animal.prototype Object.prototype null

</>复制代码

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

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

  3. 原型链:链接成 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元查看
<