首页 > 编程语言 >深入理解 JavaScript

深入理解 JavaScript

时间:2022-10-06 14:58:51浏览次数:81  
标签:执行 函数 对象 JavaScript 作用域 理解 深入 上下文 变量

原型和继承

__proto__ 属性

对象有一个隐藏属性 [[Prototype]],指向其原型(父类型),如果没有原型则为 null

从对象中读取一个不存在的属性时,会自动往原型中查找这个属性,这就是“原型继承”行为。

访问/修改 [[Prototype]] 属性的方式为

  • __proto__ 属性。__proto__ 属性是 [[Prototype]] 属性的 getter/setter,这是历史遗留问题,已经不推荐使用。
  • 推荐使用 Object.getPrototypeOf()Object.setPrototypeOf() 方法。(ES5 新增)

属性的迭代

使用 for in 循环迭代对象属性时会包含继承自原型的属性,如果不想考虑这些属性,可以通过 obj.hasOwnProperty(prop) 判断条件来过滤,如果 prop 是从原型继承来的,会返回 false

prototype 属性

JavaScript 对象分为 函数对象普通对象,每个对象都有 __ptoto__ 属性,但 只有函数对象才有 prototype 属性

构造函数、实例、原型三者的关系

(构造)函数prototype 属性指向了一个对象,这个对象就是那些被该函数构造出来的所有 实例对象原型(或者说父对象,__proto__ 所指对象),每个对象都能从原型对象继承属性。

实例的 __proto__ 指向构造函数的 ptototype 对象。

每个原型都有一个 constructor 属性,指向关联的 构造函数

function Person() {} // 构造函数
let person = new Person(); // 实例对象
person.__proto__ === Person.prototype // true
Person.prototype.constructor === Person // true

原型链

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

那么,原型的原型又是什么呢?

原型也是一个 对象,是通过 Object() 构造函数 生成的,那么原型就是这个构造函数的实例,那么它的原型就指向 Object.prototype 对象。

Object.prototype 对象是顶层对象,它的原型被设计为 null

参考:https://github.com/mqyqingfeng/blog/issues/2

参数按值传递

JavaScript 中所有函数的参数 都是按值传递的

  • 传递 基本类型值 给形参时,传递的就是 值本身
  • 传递 引用类型值 给形参时,传递的是一个 指针。(也叫按共享传递)

参数传递的本质就是一个 隐式赋值

  • 传递 基本类型变量 num1 给形参 num 时,做赋值运算:num = num1,形参保存的就是实参的值。

  • 传递 引用类型变量 obj1 给形参 obj 时,做赋值运算:obj = obj1,因为变量 obj1 保存的是一个对象的 地址,所以这个赋值运算就让形参 obj 也指向了那个对象(那块内存)。

    • 如果后续又通过另一个 赋值运算obj1 指向了另一个对象(rebinding),那么这和 obj 是无关的。
    • 而对 obj1 或者 obj修改 都是对它们所指向对象的修改(mutation),因为它们所指的是同一个对象。

    注意 rebinding 和 mutation 的区别,rebinding 之后,原来的 obj1 变量就转而保存另一个对象的地址了,和原来对象就没有联系了。

采用静态作用域

作用域 规定了 在哪里查找变量。JavaScript 采用 词法作用域,也就是 静态作用域

静态作用域 vs 动态作用域

静态作用域:函数的作用域在函数定义时就已经确定了。

动态作用域:函数的作用域在 函数调用时才确定

标签:执行,函数,对象,JavaScript,作用域,理解,深入,上下文,变量
From: https://www.cnblogs.com/lzh1995/p/16757596.html

相关文章

  • JavaScript 基础
    1.对象对象创建创建对象的两种方法:构造函数:letuser=newObject();字面量:letuser={};对象是属性可以随意添加:点号:user.name="Mason"方括号:user["age"]=26......
  • 如何将一个 JavaScript 数组打乱顺序
    当我们想将现有的数组打乱顺序,有两个方法:1.Array.prototype.sort()数组的sort()方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串......
  • 单调栈理解
    单调栈个人理解总结:1.单调栈是用来解决这一类问题:寻找数组中元素其左或者右第一个大于或小于该元素的值。2.首先,如果要寻找其右侧,要从右向左遍历。反之,从左向右遍历。3.......
  • JavaScript回调函数
    在百度百科中,回调函数的定义就是一个被作为参数传递的函数。通俗地理解:我现在写一个函数,里面定义了函数A,那么函数A就是回调函数。以前我认为JavaScript不过是......
  • 深入理解linux内核第三版(三)中断和异常
    中断:也叫异步中断,是由外设产生的。异常:也叫同步中断,是由CPU产生的,是指令执行过程中产生的。中断信号的作用:中断信号提供了一种特殊的方式,使处理器转而去运行正常控制流之......
  • 从这两道题重新理解,JS的this、作用域、闭包、对象
    日常开发中,我们经常用到this。例如用Jquery绑定事件时,this指向触发事件的DOM元素;编写Vue、React组件时,this指向组件本身。对于新手来说,常会用一种意会的感觉去判断this的指......
  • 深入理解JS作用域链与执行上下文
    变量提升:变量提升(hoisting)。我可恨的var关键字:你读完下面内容就会明白标题的含义,先来一段超级简单的代码:<scripttype="text/javascript">varstr='Hello......
  • 深入理解AQS--jdk层面管程实现【管程详解的补充】
    什么是AQS1.java.util.concurrent包中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这些行为的抽象就是基于AbstractQ......
  • JavaScript水平滚动菜单切换
         完整代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><met......
  • 对话系统中的中文自然语言理解(NLU)
    当第一次看到自然语言理解的时候,我是感到困惑的。因为自然语言处理的目的就是要去理解人类产生的文本信息,从这个角度讨论,那应该所有的自然语言处理任务,都应该自然语言理解......