-
2022-02-22 23:28:10
原型可以解决什么问题:
对象共享属性和方法
谁有原型:
函数拥有:prototype
对象拥有:proto
对象查找属性或者方法的顺序:
先在对象本身查找–>构造函数中查找–>对象的原型中查找–>构造函数的原型中查找–>当前原型中查找
原型链的最顶端是null更多相关内容 -
技术分享经典 javaScript原型链面试题
2022-01-28 11:27:40技术分享 javaScript原型链一个小题目前置知识变量提升和函数提升this指针的指向原型链是什么new操作符的工资流程 一个小题目 今天我们部门的技术分享上出现了这样一段代码: function Foo(){ getName=function(){...一个小题目
今天我们部门的技术分享上出现了这样一段代码:
function Foo(){ getName=function(){console.log(1)} return this }//1 Foo.getName=function(){console.log(2)}//2 Foo.prototype.getName=function(){console.log(3)}//3 var getName=function(){console.log(4)}//4 function getName(){console.log(5)}//5 getName() Foo().getName() getName() Foo.getName() new Foo.getName() new Foo().getName() new new Foo().getName()
问我们这段代码的运行结果是怎样的
前置知识
首先我们需要了解以下前置知识:
- 变量提升和函数提升 ;
- this指针的指向;
- 原型链是什么 ;
- new操作符的工资流程;
本文对于这些知识进行浅谈,详细的知识作者还是建议读者去自行查找资料和学习。
变量提升和函数提升
变量提升简单来说就是使用var声明变量的时候,会在编译时将其提升至最顶端,例如本题的代码的前几行:(有错误)
//编译前 function Foo(){ getName=function(){console.log(1)} return this } Foo.getName=function(){console.log(2)} Foo.prototype.getName=function(){console.log(3)} var getName=function(){console.log(4)} function getName(){console.log(5)} //编译后 var getName;//getName=undefined function Foo(){ getName=function(){console.log(1)} return this } Foo.getName=function(){console.log(2)} Foo.prototype.getName=function(){console.log(3)} getName=function(){console.log(4)} function getName(){console.log(5)}
当然细心的读者应该会发现,这个编译后的代码依旧存在一些问题,因为js不仅有变量提升,同时还有函数提升。
在JS中函数在编译后也会提升至最顶端,因此编译后的正确代码为:
function Foo(){ getName=function(){console.log(1)} return this } function getName(){console.log(5)}//函数声明 var getName;//变量声明 Foo.getName=function(){console.log(2)} Foo.prototype.getName=function(){console.log(3)} getName=function(){console.log(4)}
这里要注意:函数提升的优先级高于变量提升,当函数声明与变量名相同时,只要变量未赋值,此名称依旧是个函数,不会被覆盖;只有当变量赋值后,函数声明才会被同名的变量覆盖。
相信读到这里开篇提到的问题已经能解决一部分了
getName=function(){console.log(4)}
会覆盖同名函数,因此第一行的执行结果为4
this指针的指向
简单来说this是一个指向一个对象的指针,通常情况下你只需要记住调用方法时谁调用,this就指向谁。
例如我在全局中调用Foo()方法,那么此时进入方法里this的指向就是全局(Window对象)
那么我们第二行的运行结果也就很容易就理解了,首先Foo方法对全局里的getName重新赋值,并返回Window对象,所以第二行执行的方法为全局对象里重新赋值后的的getName()
因此第二行和第三行的执行结果为1
读到这里第三行的运行结果和第二行一样也不难理解了原型链是什么
首先我们知道在js中函数也是一个对象,它也是具有普通对象的一些功能的,而JavaScript 对象体系是基于构造函数和原型链的。继承不通过类,而是通过原型对象实现,原型对象的所有属性和方法,都能被实例对象共享。
既然函数可以是一个对象,那么原题中的第二部分,就是为Foo添加了一个属性getName(),所以第4行的输出结果就是现在为其添加的这个方法的运行结果:2
接下来我们需要了解原题中第三部分的作用,也就是以下代码的作用:
Foo.prototype.getName = function () { console.log(3) }
首先每个构造函数都有一个prototype属性指向原型对象,用来存放共有属性和方法的地址。
每个实例对象都有一个__proto__属性指向构造函数的原型对象。
例如本题的Foo.__proto__===Function.prototype//true Function.prototype.__proto__===Object.prototype//true
这样依次类推各个原型组成了“原型链”
在理解了原型链之后你还需要了解下面这句话:
当js试图得到一个对象的属性时,会先去这个对象的本身去寻找,如果这个对象本身没有找到这个属性,那么js就会去它构造函数的’prototype’属性中去寻找,也就是去’proto‘中寻找,如果’prototype’属性本身中依旧没有找到,’prototype’中依旧有一个‘proto’。读到这里相信第三部分的代码意思也很清晰了,向原型链中添加一个方法:getName()
new操作符的工资流程
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
简单来说new就是用来创建一个对象。
那么new操作符是怎么做到的呢?
第一步:创建一个空的对象(即{})
第二步:将空对象的原型prototype指向构造函数的原型
第三步:改变this指针的指向,并将剩余的参数传入,执行构造函数中的代码
第四步:判断构造函数的返回值,将成功后的对象返回
这时我们分析原题第五行的输出结果:
第一步:创建一个空对象
let obj= {}
第二步:将obj的原型指向Foo对象的getName()的原型
obj.__proto__=Foo.getName.prototype
第三步:改变this指向,传入剩余参数并执行构造函数Foo.getName()。运行到这里输出3。
第四步:判断构造函数的返回值,将成功后的对象返回
最后我们再看第六行的运行过程:
首先new Foo().getName()等价于(new Foo()).getName()第一步:创建一个空对象
let obj= {}
第二步:将obj的原型指向Foo的原型
obj.__proto__=Foo().prototype``` 第三步:改变this指向,传入剩余参数并执行构造函数Foo() 第四步:判断构造函数的返回值,将成功后的对象返回 第五步:执行返回的新对象的getName()方法,可我们的新对象中并没有此方法,于是去原型链上寻找,故输出3 相信读到这里最后一行的答案也不需要作者多说什么了,其运行过程与第六行的基本一致。
-
JS原型与原型链(面试题)
2022-01-14 15:56:27原型 原型分为两种 ...原型链 获取对象时,如果这个对象身上本身没有这个属性时,它就会去他的原型__proto__上去找,如果还找不到,就去原型的原型上去找…一直找到最顶层(Object.prototype)为止,Ob原型
原型分为两种
prototype
- 每一个函数都会有prototype属性,被称为
显式原型
。
__proto__
- 每一个实例对象都会有__proto__属性,其被称为
隐式原型
。
constructor
每一个prototype原型上都会有一个constructor属性,指向它关联的构造函数。
原型链
- 获取对象时,如果这个对象身上本身没有这个属性时,它就会去他的原型
__proto__
上去找,如果还找不到,就去原型的原型上去找…一直找到最顶层(Object.prototype
)为止,Object.prototype对象也有__proto__
属性值为null。
这里需要注意的是,Object是原型链的最顶层,所有构造函数的prototype都指向Object.prototype
-
JS-原型与原型链面试题
2021-04-08 16:56:22function A() { } A.prototype.n = 1 var b = new A() A.prototype = { ... // A的原型对象被改变了,但是b的原型对象可没变 var c = new A() console.log(b.n, b.m, c.n, c.m) //1 underfined ...function A() { } A.prototype.n = 1 var b = new A() A.prototype = { n: 2, m: 3 } // A的原型对象被改变了,但是b的原型对象可没变 var c = new A() console.log(b.n, b.m, c.n, c.m) //1 underfined 2 3
2.function F () {} Object.prototype.a = function() { console.log("a()"); } Function.prototype.b = function() { console.log("b()"); } var f = new F() f.a() //a() // f.b() f.b不是一个函数 未捕获类型错误 F.a() //a() F.b() b()
-
js面试题--原型和原型链
2021-10-18 10:23:58一、class 和 继承 1. 基本实现 class的核心:constructor、属性、方法。 继承的核心:extends、super、扩展或重写方法。 class和继承 详细说明链接:Class 类_小豪boy的博客-CSDN博客_class 2.... 原型链 -
JS-原型与原型链常见面试题
2021-04-11 08:37:53原型与原型链的常见面试题 1. var A=function(){} A.prototype.n=1 var b=new A() A.prototype={ n:2, m:3 } var c=new A() console.log(b.n,b.m,c.n,c.m)//1,undefined,2,3 分析一下:b.n 因为b是A的实例... -
原型和原型链面试题
2021-05-26 16:31:20javascript原型与原型链 每个函数都有一个prototype属性,被称为显示原型 每个实例对象都会有_ _proto_ _属性,其被称为隐式原型 每一个实例对象的隐式原型_ _proto_ _属性指向自身构造函数的显式原型prototype 每个... -
【JS面试题】原型链
2020-07-19 07:13:29major) { super(name) this.major = major } teach() { console.log(`${this.name} 教授 ${this.major}`) } } //原型链 console.log(Student.prototype.__proto__) console.log(People.prototype) console.log... -
【JavaScript】5.面试题一原型和原型链
2017-09-28 07:03:59一、题目 1、如何准确判断一个变量是数组类型? var array=[]; console.log(array instanceof Array);//true 判断引用类型的具体类型要用...2、写一个原型链继承的的例子 //封装一个DOM查询实例 functio -
JavaScript 面试题(十二)原型和原型链是什么?
2021-08-26 20:30:49原型链: 当访问一个对象的某个属性时,会首先在这个对象本身的属性上查找,如果没有找到,则在它的proto隐式原型上查找,即它的构造函数的prototype。如果还没有找到,就去它的构造函数的prototype对象的proto隐式... -
面试题集合-js-01原型链
2019-08-27 09:01:29面试中的重要问题,我遇到过的面试问题中,原型链被问到的几率特别大,所以整理一个笔记记录下来我对原型链的理解。 每个构造函数(constructor)都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针... -
前端面试题:JS中的原型和原型链
2020-07-24 10:48:24JS的原型和原型链算是前端面试题的热门题目了,也是参加了几场面试,感觉好多次都被问到对原型和原型链的理解,所以今天也是索性把他给整理出来,一方面方便自己以后复习查看,另一方面也是给大家分享一下我对原型和... -
面试题 - JavaScript 中原型及原型链
2019-12-15 22:47:24JavaScript 中的继承主要是通过原型来实现。而原型继承少不了两个重要的属性 __proto__ 和 prototype。今天整理一下前端面试题中的原型和原型链题目。 -
【前端面试题】原型和原型链-js
2022-03-15 00:34:49【前端面试题】原型和原型链-js -
原型与原型链的常见面试题
2017-10-27 09:04:43//测试题1 var A=function(){} A.prototype.n=1 var b=new A() A.prototype={ n:2, m:3 } var c=new A() console.log(b.n,b.m,c.n,c.m)//1,undefined,2,3 //测试题2 var F=function(){}; Object.... -
JavaScript 原型链和继承面试题
2020-10-29 02:00:37JavaScript 原型链和继承问题 JavaScript 中没有类的概念的,主要通过原型链来实现继承。通常情况下,继承意味着复制操作,然而 JavaScript默认并不会复制对象的属性,相反,JavaScript只是在两个对象之间创建一个... -
JS面试题—原型和原型链
2017-08-08 17:19:35写一个原型链继承的例子 描述new一个对象的过程 二、知识点 1.构造函数 function Foo(name, age){ this.name = name this.age = age this.class = 'class-1' // return this //默认有这一行 -
前端面试题之原型链常见面试题总结
2021-02-07 19:54:492.写一个原型链继承的例子 //动物的构造函数,有一个方法eat function Animal() { this.eat = function () { console.log('animal eat'); } } //狗的构造函数,有一个方法bark function Dog() { thi -
[JS]深入理解原型和原型链以及区别(包含面试题详解)
2022-05-09 16:33:30原型 一个可以被复制(或者叫克隆)的一个类,通过复制原型可以创建一个一模一样的新对象,也可以说原型就是一个模板,在设计语言中更准确的说是一个对象模板 ...说说对原型的理解(面试题) 在 Jav -
面试题准备(一):原型、原型链
2022-02-18 17:51:05文章目录原型 原型 -
JS(原型和原型链)整理的面试题
2019-09-07 17:29:54写一个原型链继承的例子 实例:封装 DOM 查询 定义构造函数 Elem,属性封装成 id 打印出所有的 html 将所有的 html 变为 hello imooc ,并且点击弹出 ‘clicked’ 链式操作 题目3.描述 new 一个对象的过程 1.... -
js的面试与笔试--JavaScript prototype原型和原型链详解
2018-07-27 17:48:31用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级... -
JS经典面试题04-原型链Foo.getName
2020-06-08 10:21:46预解析 */ /* 题干 */ //1.声明全局函数Foo function Foo() { //声明全局变量getName : 本质给window添加getName方法 getName = function () { console.log(1); }; /* 没有使用new : this指向window 使用new : ... -
Web前端面试题目JavaScript(作用域,原型。原型链,闭包,封装函数).txt
2020-07-06 20:12:27前端面试题,包含JavaScript的闭包,作用域,原型,原型链,上下文环境以及DOM,BOM封装函数深度克隆,以及一些常见的·JS问题,试题简单但是容易混淆,作为前端工程师必考题 -
面试题讲解(一)---原型链
2021-05-29 20:09:00JS面试题: 框架 js基础知识:1. 原型链 2. 事件循环 3. 执行上下文 第三方库 基础知识 所有的对象都是通过new 函数()创建的,该函数叫做构造函数 函数可以产生对象 所有对象都是靠函数产生的 函数也是一个... -
原型链面试题
2020-12-12 21:56:57测试题1 var A = function() {} A.prototype.n = 1 var b = new A() A.prototype = { n: 2, m: 3 } var c = new A() console.log(b.n, b.m, c.n, c.m) // 1 undefined 2 3 测试题2 var F = function() {} ... -
原型链面试问题
2019-06-27 12:12:28创建对象有几种方法 字面量 //字面量 var o1 = {name:'o1'} var o2 = new Object({name:'o2'}) //构造函数 var M = function(name){ this.name = name ...// Object.create Object.create是用原型链的方... -
JS原型应用-面试题
2022-01-16 23:01:15原型链含义:因为每个对象和原型都有隐式原型,对象的隐式原型指向创建该对象的构造函数的原型对象,而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链。(原型链的查找属性是从下往上的过程) 附上... -
面试中如何去回答原型链这个问题的思考
2021-09-02 17:14:50面试中问到了关于原型链的什么 我的回答如下: 所有的JS对象都有一个prototype属性,指向它的原型对象。当试图访问一个对象的属性时,如果没有在该对象上找到,它还会搜寻该对象的原型,以及该对象的原型的原型,... -
原型原型链 面试题
2019-10-07 13:28:51//测试题1 var A=function(){} A.prototype.n=1 var b=new A() A.prototype={ n:2, m:3 } var c=new A() console.log(b.n,b.m,c.n,c.m)//1,undefined,2,3 //测试题2 var F=function(){}; Object.proto...