JS三座大山

js三座大山——原型及原型链 前言 js的三座大山(原型及原型链、作用域及闭包,异步执行机制及单线程),一直是前端学习和面试中常常遇到的话题,所以深入学习这一块的知识还是很有必要的,下面详细讲解一下我对这一块的理解,记录一下学习过程。这一节主要讲一下原型及原型链,js是面向对象编程,在es6提出class概念前是如何实现类及继承关系的呢,就是通过原型和原型链来实现的。 一、构造函数、实例、原型对象 通过一个例子来看一下这三者之... 阅读详情

前言

本篇文章比较适合3年以上的前端工作者,JS三座大山分别指:原型与原型链,作用域及闭包,异步和单线程。

原型与原型链

说到原型,就不得不提一下构造函数,首先我们看下面一个简单的例子:

复制代码

function Dog(name,age){   
    this.name = name;
    this.age = age;
}

let dog1 = new Dog("哈士奇",3);
let dog2 = new Dog("泰迪",2);

复制代码

首先创造空的对象,再让this指向这个对象,通过this.name进行赋值,最终返回this,这其实也是new 一个对象的过程。

其实: let obj = {} 是 let obj = new Object()的语法糖; let arr = [] 是 let arr = new Array()的语法糖; function Dog(){...} 是 let Dog = new Fucntion()的语法糖。

那什么是原型那?在js中,所有对象都是Object的实例,并继承Object.prototype的属性和方法,但是有一些是隐性的。

我们来看一下原型的规则:

1.所有的引用类型(包括数组,对象,函数)都具有对象特性;可自由扩展属性。

var obj = {};
obj.attribute = "三座大山";
var arr = [];
arr.attribute = "三座大山";
function fn1 () {}
fn1.attribute = "三座大山";

2.所有的引用类型(包括数组,对象,函数)都有隐性原型属性(__proto__),值也是一个普通的对象。

console.log(obj.__proto__);

3.所有的函数,都有一个prototype属性,值也是一个普通的对象。

console.log(obj.prototype);

4.所有的引用类型的__proto__属性值都指向构造函数的prototype属性值。

console.log(obj.__proto__ === Object.prototype); // true

5.当试图获取对象属性时,如果对象本身没有这个属性,那就会去他的__proto__(prototype)中去寻找。

复制代码

function Dog(name){ 
   this.name = name; 
} 
Dog.prototype.callName = function (){ 
   console.log(this.name,"wang wang"); 
}
let dog1 = new Dog("Three Mountain"); 
dog1.printName = function (){ 
   console.log(this.name);
}
dog1.callName();  // Three Mountain wang wang
dog1.printName(); // Three Mountain

复制代码

原型链:如下图。

我找一个属性,首先会在f.__proto__中去找,因为属性值为一个对象,那么就会去f.__proto__.__proto__去找,同理如果还没找到,就会一直向上去查找,直到结果为null为止。这个串起来的链即为原型链。

 作用域及闭包

讲到作用域,你会想到什么?当然是执行上下文。每个函数都有自己执行上下文的excution context,和variable object。这些环境用于储存上下文中的变量,函数声明,参数等。只有函数才能制造作用域。

PS:for if else 不能创造作用域。

复制代码

console.log(a) ; // undefined
var a = 1;

//可理解为
var a;
console.log(a);  // undefined
a = 1;

复制代码

执行console.log时,a只是被声明出来,并没有赋值;所以结果当然是undefined。

this

本质上来说,在js里this是一个指向函数执行环境的指针。this永远指向最后调用它的对象,并且在执行时才能获取值,定义是无法确认他的值。

复制代码

var a = { 
    name : "A", 
    fn : function (){
        console.log (this.name) 
    } 
} 
a.fn() // this === a 
a 调用了fn() 所以此时this为a

a.fn.call ({name : "B"}) // this === {name : "B"} 
使用call(),将this的值指定为{name:"B"}

var fn1 = a.fn 
fn1() // this === window
虽然指定fn1 = a.fn,但是调用是有window调用,所以this 为window

复制代码

this有多种使用场景,下面我会主要介绍4个使用场景:

1.作为构造函数执行

function  Student(name,age) {
    this.name = name           // this === s
    this.age = age             // this === s
    //return  this
}
var s = new Student("py1988",30)

首先new 字段会创建一个空的对象,然后调用apply()函数,将this指向这个空对象。这样的话,函数内部的this就会被空对象代替。

2.作为普通函数执行

function  fn () {
    console.log (this)       // this === window
}
fn ()

3.作为对象属性执行

复制代码

var obj = {
    name : "A",
    printName :www.wanmeiyuele.cn   unction () {
        console.log (this.name) www.boshenyl.cn  // this === obj
    }
}
obj.printName ()

复制代码

4.call(),apply(),bind()

三个函数可以修改this的指向,具体请往下看:

复制代码

var name = "小明" , age = "17"
var obj = { 
    name : "安妮", 
    objAge : this.age, 
    fun : function () { 
            console.log ( this.name + "今年" + this.age ) 
        } 
} 
console.log(obj.objAge) // 17 
obj.fun() // 安妮今年undefined

复制代码

复制代码

var name = "小明" , age = "17" 
var obj = { 
    name : "安妮", 
    objAge :this.age, 
    fun : function (like,dislike) { 
              console.log (this.name www.douniu157.com + "今年" + this.age ,"喜欢吃" + like + "不喜欢吃" + dislike) 
           } 
    } 
var a = { name : "Jay", age : 23 } 
obj.fun.call(a,"苹果","香蕉") www.chuangyed.com // Jay今年23 喜欢吃苹果不喜欢吃香蕉 
obj.fun.apply(a,["苹果","香蕉"]) // Jay今年23 喜欢吃苹果不喜欢吃香蕉 
obj.fun.bind(a,"苹果","香蕉")() // Jay今年23 喜欢吃苹果不喜欢吃香蕉

复制代码

首先call,apply,bind第一个参数都是this指向的对象,call和apply如果第一个参数指向null或undefined时,那么this会指向windows对象。

call,apply,bind的执行方式如上例所示。call,apply都是改变上下文中的this,并且是立即执行的。bind方法可以让对应的函数想什么时候调用就什么时候调用。

闭包

闭包的概念很抽象,看下面的例子你就会理解什么叫闭包了:

复制代码

function a(){
  var n = 0;
  this.fun = function () {
    n++; 
    console.log(n);
  };
}
var c = new a();
c.fun();  //1
c.fun();  //2

复制代码

闭包就是能够读取其他函数内部变量的函数。在js中只有函数内部的子涵数才能读取局部变量。所以可以简单的理解为:定义在内部函数的函数。

用途主要有两个:

1)前面提到的,读取函数内部的变量。

2)让变量值始终保持在内存中。

 异步和单线程

我们先感受下异步。

console.log("start");
setTimeout(function (www.huayi1.cn/) {
    console.log("medium");
}, 1000);
console.log("end");

使用异步后,打印的顺序为 start-> end->medium。因为没有阻塞。

为什么会产生异步呢?

首先因为js为单线程,也就是说CPU同一时间只能处理一个事务。得按顺序,一个一个处理。

如上例所示,第一步:执行第一行打印 “start”;第二步:执行setTimeout,将其中的函数分存起来,等待时间结束后执行;第三步:执行最后一行,打印“end”;第四部:处于空闲状态,查看暂存中,是否有可执行的函数;第五步:执行分存函数。

为什么js引擎是单线程?

js的主要用途是与用户互动,以及操作DOM,这决定它只能是单线程。例:一个线程要添加DOM节点,一个线程要删减DOM节点,容易造成分歧。

为了更好使用多CPU,H5提供了web Worker 标准,允许js创建多线程,但是子线程受到主线程控制,而且不得操作DOM。

任务列队

单线程就意味着,所有的任务都要排队,前一个结束,才会执行后面的任务。如果列队是因为计算量大,CPU忙不过来,倒也算了。但是更多的时候,CPU是闲置的,因为IO设备处理得很慢,例如 ajax读取网络数据。js设计者便想到,主线程完全可以不管IO设备,将其挂起,然后执行后面的任务。等后面的任务结束掉,在反过头来处理挂起的任务。

好,我们来梳理一下:

1)所有的同步任务都在主线程上执行,行程一个执行栈。

2)除了主线程之外,还存在一个任务列队,只要一步任务有了运行结果,就在任务列队中植入一个时间。

3)主线程完成所有任务,就会读取列队任务,并将其执行。

4)重复上面三步。

只要主线程空了,就会读取任务列队,这就是js的运行机制,也被称为 event loop(事件循环)。

2021哈工大网安837考研初试经验贴 这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar 阅读详情

相关推荐

AD创建属于自己的元件库(详细)

我今天开始学习AD2022,但是我想自己创建属于自己的元件库,但是奈何找了好多教程就是随便几句话就把我打发走了,弄了一天都没搞定(也许是我比较菜),所以现在乱懂了,自己写一个属于我们自己小白的教程,希望有用吧哈哈我比较偷懒,直接使用嘉立创上画好的元件导入,和我们自己创建自己画的步骤其实都一样。

qq_33591173的博客 2万+

JavaScript 的三座大山

js 作为前端的中坚力量。那么 javascript 三座大山,你知道是哪些呢?

xxxzzzqqq_的博客 545

四旋翼无人机Matlab建模

本文主要分享一下四旋翼无人机的建模过程,然后在Matlab的simulink模块搭建起四旋翼无人机的模型,下一章将结合这个模型设计双环PID控制器并调节参数。 一、无人机建模过程

qq_36903625的博客 3万+

详细理解JS的三座大山

详细理解JS的三座大山

辉生活-记录程序生活的点滴。 1038

实战详细讲解Qt插件plugin的编写与用法

qt插件的开发,可以说是动态库的开发,因为调用方式类似,多熟悉一下,利用Qt框架开发很简单的。在想想这种调用过程有的熟悉,比如公司买了一堆摄像头,公司要对摄像头进行二次开发,实现自己想要的功能,集成到一套设备里去,然后在卖给用户。此时厂商肯定会提供开发文档,并给你SDK包(软件开发工具包), 包里你会发现只有头文件和一堆库文件,没有源文件,因为实现的过程是产商公司保密的,给你看还得了。所以都封装成了库的形式给你调用,如静态库或者动态库。

qq_44667165的博客 1万+

vivado下ECO操作-不重新综合实现修改属性并生成.bit

ECO即engineer change order,即工程变更指令,可以对设计做局部小改动并只对改动部分重新布局布线并生成.bit。在一个工程动辄编译几个小时情况下,可以在调试中节省大量时间。比如我们在调试中,需要改变时钟占空比或者相位,需要改变寄存器初值等等,此时用ECO暂时改动,待验证后在重新编译无疑是最有效率的方法。 实现ECO通常有两种方式,一是通过vivado界面完成,另一种方法就是tcl脚本。所有的ECO操作都可以通过tcl操作完成,有的操作用vivado界面无法完成,只能通过tcl。以下主要

4657

攻克JavaScript 的三座大山

基本语法:了解 JavaScript 的基本语法,包括变量声明、数据类型、运算符、条件语句、循环语句等。数据类型和类型转换:熟悉 JavaScript 的数据类型,包括原始数据类型(字符串、数字、布尔值、null、undefined)和复杂数据类型(对象、数组、函数等),以及类型转换的规则。函数:深入理解函数的定义、调用、参数传递和返回值,并掌握闭包、匿名函数和箭头函数等概念。对象和面向对象编程:了解 JavaScript 中的对象、原型和原型链,学习面向对象编程的基本思想和实现方式。

qq_66627105的博客 1899

生物信息学工具链搭建:用conda一键搞定MCScanX所有依赖(Ubuntu20.04实测)

本文详细介绍了在Ubuntu20.04系统上使用conda一键部署MCScanX及其所有依赖的高效方法,解决了传统源码编译安装中的依赖冲突问题。通过conda环境管理工具,研究者可以快速搭建生物信息学工具链,实现基因组共线性分析的高效运行,显著提升研究效率。

backprop5master的博客 247

JS三座大山 —— 原型和原型链

利用流程图带你全方面理解原型和原型链!构造函数通过prototype属性指向原型对象,原型对象包含了共享的属性和方法,而对象实例通过原型链(__proto__属性指向原型对象)继承了原型对象的属性和方法。通过属性,我们可以追溯到对象实例的构造函数。这些概念共同构成了 JavaScript 中的原型继承机制。

悟其浅而深修,沉其心而精进 2554

【华为OD机试】创建二叉树(python, java, c++, js)

请按下列描达构建一颗二叉树,并返回该树的根节点: 1、先创建值为-1的根结点,根节点在第0层; 2、然后根据operations依次添加节点: operations[i] = [height, index] 表示对第 height 层的第index 个节点node, 添加值为i 的子节点: 若node 无「左子节点」。则添加左子节点; 若node 有「左子节点」但无「右子节点」,则添加右子节点: 否则不作任何处理。 height、index 均从0开始计数;index 指所在层的创建顺序。

A_D_I_D_A_S的博客 188

InVEST模型 | HAbitat quality模块计算生境质量

 本文详细介绍使用InVEST模型中HAbitat quality模块计算生境质量,包含各个参数的含义、所需数据、数据处理以及需要各个参数注意的地方等过程。

地理空间科学的博客 1万+

详解JavaScript 的三座大山:作用域和闭包、原型和原

某量化私募-社会招聘-量化交易员(高频做市)-深圳、上海、香港工作内容:●研究、开发和维护针对数字货币市场的高频做市策略●监控和分析交易表现,根据实际情况调整策。rpc技术 RPC技术解决了分布式系统中,服务与服务之间的调用问题。它还能够提供跨语言支持、协议。JavaScript 中有三个重要概念,即作用域和闭包、原型和原型链、异步和单线程。这些概念在日常的开发工作中经常被提及,并对我们理解和编写高质量的JavaSc。#牛客在线求职答疑中心#24届京东TET管培会有第二批吗?

2301_78234743的博客 145

word多级列表为什么会变成黑块解决思路

今天在写文档时,发现WORD5级的标题都变黑块了,找了度娘的资料,终于解决了。 第一种 1、光标bai放在黑快的右边,按向左的箭头,然后ctrl+shift+s,点击重新应用。 2、点击“定义新的多级列表”(不知道从哪儿找这个按钮的百度下),直接点确定。 3、这里很重要!!!不要直接保存,而是直接关掉word,会提示保存还是不保存,这个地方再点击保存。 第二种 Word2016 使用宏代码修复方法 1.找到视图-宏,打开 查看宏 2.创建宏 3.贴...

霍力强的专栏 8580

js三座大山

#1、原型与原型链, #2、作用域及闭包, #3、异步和单线程, 原型与原型链 说到原型,就不得不提一下构造函数,首先我们看下面一个简单的例子: function Dog(name,age){ this.name = name; this.age = age; } let dog1 = new Dog("哈士奇",3); let dog2 = new Dog("泰迪",2);...

flykus的博客 2195

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

前端javascript总结笔记(一)--js的三座大山

前言: 第一章为变量类型和计算。 第二章到第四章分别是原型与原型链,作用域及闭包,异步和单线程,这三个就是我们说的三座大山。 一、变量类型和计算 1:JS中使用typeof能得到哪些类型? 字符串(String)、数值(Number)、布尔值(Boolean)、Undefined、[Null对象,数组(Array),函数(Function) ](Object)共5种 2:何时使用=...

单车去旅行的博客 2373

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

前端面试送命题-JS三座大山-2020年12月2日

前言 本篇文章比较适合 3 年以上的前端工作者,JS 三座大山分别指:原型与原型链,作用域及闭包,异步和单线程。 原型与原型链 说到原型,就不得不提一下构造函数,首先我们看下面一个简单的例子: function Dog(name,age){ this.name = name; this.age = age; } let dog1 = new Dog("哈士奇",3); let dog2 = new Dog("泰迪",2); 首先创造空的对象,再让 this 指向这个对...

余生若枫 311

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

JavaScript 三座大山

原型与原型链及this声明:下面说的对象是指 object Array Function 除 null 以外 1 任何对象 都可以做自由添加属性var obj = {a:10, b:1} obj.qq = "123456"; //Object {a: 10, b: 1, qq: "123456"}2 在JavaScript中任何对象都会有__proto__ 属性 (隐式原型)3 在JavaSc

未来以来 futureToday 2513

前端面试送命题-JS三座大山

前言本篇文章比较适合3年以上的前端工作者,JS三座大山分别指:原型与原型链,作用域及闭包,异步和单线程。原型与原型链说到原型,就不得不提一下构造函数,首先我们看下面一个简单的例子:function Dog(name,age){ this.name = name; this.age = age; } let dog1 = new Dog("哈士奇",3); let dog2 ...

li123128的博客 5155

理解JS的三座大山

JS的三座大山

楠姐的博客 1万+

js三座大山——作用域及闭包

前言 在了解闭包之前,应该先了解作用域和作用域链的概念,简单的说作用域即变量起作用的范围,作用域链即作用域在上下文中的关系。在es6新语法之前,变量只有两种,即全局变量和局部变量。 一、作用域 一般来说,全局变量是指定义在函数最外层的变量,所有函数都可以直接访问,局部变量是指定义在函数内部,指允许在函数内部访问,函数外部一般访问不到。 var a = '全局变量'; function foo() ...

学习ing 295

JS三座大山之原型链

在JS中原型链的概念刚开始可能一直迷惑着大多数人,我也一样,不过花点时间仔细的梳理梳理,还是很容易理解的。本文就着重介绍一下原型链,如有不对之处,欢迎指正,共同探讨,共同进步。 在面试时,面试官可能会通过对象的创建方式来引出原型链相关的问题: 那么创建对象的方式主要有以下几种: 第一种: 字面量 var Obj1 = {name:”o1”}; var Obj2 = new Object({name...

Rampage_w的博客 505

web前端面试高频考点——JavaScript 篇(一)【JS的三座大山 】 原型和原型链、作用域和闭包、异步

web前端面试高频考点 —— JavaScript 篇(一)【JS的三座大山 】 变量类型和计算、原型和原型链、作用域和闭包、异步(直击重难点,修炼内功必备)

HuoZhiyan 的博客 2847

前端面试送命题 - JS三座大山

关注“重度前端”助力前端深度学习━━━━前言本篇文章比较适合 3 年以上的前端工作者,JS 三座大山分别指:原型与原型链,作用域及闭包,异步和单线程。原型与原型链说到原...

zz_jesse的博客 268

js三座大山----(第三座山)

JS三座大山再学习(三、异步和单线程) 前言 写这一篇的时候,BiKaBi查阅了很多资料和文章,但是相当多的文章写的都很简单,甚至互相之间有矛盾,这让我很困扰;同时也让我坚定了要写出一篇好的关于JS异步、单线程、事件循环的文章,下面,让我们一起来学习本文吧,冲鸭~~ 单线程 什么是单线程 //栗子1 console.log(1) console.log(2) console.log(3) /...

weixin_43932097的博客 1524
上一篇: js数组方法总结
下一篇: 详解JavaScript中的Event Loop(事件循环)机制
zeroyulong
博客等级 码龄10年 55粉丝 127原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值