我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScript中实现new的两种方式引发的探究

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScript中实现new的两种方式引发的探究

前言

当你 new 一个构造函数时发生了什么?

“众所周知”的三步:

创建一个空对象,将它的引用赋给 this,继承函数的原型;通过 this 将属性和方法添加至这个对象;最后返回 this 指向的新对象,也就是实例。

一般来说在js中大概是这样的:


function Mynew(parent,...rest){
	let obj={};
	obj.__proto__=parent.prototype;
	let res=parent.apply(obj,rest);
	return typeof res=="object"?res:obj;
}

上面提到的“空对象”只是简称。事实上,就算是定义一个 {} ,它也会从 Object.prototype 上继承很多方法和属性。
《JavaScript语言精髓与编程实践》中提出了一个“更加空白的对象”:它有两种情况 —— Constructor.prototype 值为null;或者Object.getPrototypeOf(obj) 值为null。

但通常我们还能见到另一种写法:


function Mynew_2(parent,...rest){
	let child=Object.create(parent.prototype);
	let result=parent.apply(child,rest);
	return typeof result=="object"?result:child;
}

这两种实现的不同无疑引起了我的兴趣!


Object.create()是怎么实现的?

我们来看一段代码:


var Best1=function(){
	this.a=2;
}
var o1=Object.create(Best1);
var o2=Object.create(Best1.prototype);
console.log(o1.a); // undefined
console.log(o2.a); // undefined

test1

可以看到,以 o1 为例,Object.create() 失去了对原来对象属性的访问,而 o2 …同理。

再来看另一段代码:


var Best=function(){
	this.a=2;
}
Best.prototype.a=3;
var o1=Object.create(Best);
var o2=Object.create(Best.prototype);
console.log(o1.a); // undefined
console.log(o2.a); // 3

test2

到这里,我似乎明白了什么,又似乎没明白…

我决定这么做:


let b=new Best();
console.log(b);

test3


console.log(Best.prototype);

test4

恍然大悟!

原来我们平时说的 “当读取实例属性时,如果找不到,就会查找与对象关联的原型中的属性;如果还找不到,就去找原型的原型,直到最顶层(__proto__ 为null)为止” 是指 “一直顺着 __proto__ 向上查找”(注意:不经过prototype!)。

__proto__prototype 之间又有什么呢?


console.log(b.__proto__);
console.log(Best.prototype);

test5

哦!这就是我们常听到的“实例的 __proto__ 等于对象的 prototype ”吧。

那现在回过头来,打印一下 o2 这个对象:


console.log(o2);

test6

你有没有想到什么?

根据上面所描述的那样,o2 就是 Best 的实例啊!

所以说,create() 函数实际上返回了一个对象的实例?

但 o1 仍然“不为所动”!

test7

所以我们能否猜测:在 Object.create() 函数中应该是拿到对象的原型并以实例的形式返回:


Object.create=function(o){
	let F=function(){};
	F.prototype=o;
	return new F();
}

为什么这里要用函数再 new 的方式?而不是直接用对象去接收?

test8

这和“为什么vue中data是一个函数而不是直接的对象”其实是一个问题:JavaScript中的对象是引用类型,在一个实例中改变某一个元素的值其余实例的值都会发生改变!

而通过create函数则不会:

test8

总结

到此这篇关于JavaScript中实现new的两种方式的文章就介绍到这了,更多相关JS实现new的方式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScript中实现new的两种方式引发的探究

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Go语言中字符串拼接的实现方式探究

Go语言中字符串拼接的实现方式探究在Go语言中,字符串是不可变的,即一旦创建后就无法直接修改其内容。因此,在进行字符串拼接时,需要特殊的处理方式来保证效率和性能。本文将探究Go语言中字符串拼接的实现方式,包括常用的几种方法以及它们的特点和
Go语言中字符串拼接的实现方式探究
2024-03-12

Android中button实现onclicklistener事件的两种方式

代码如下: package com.demos; import android.app.Activity; import android.os.Bundle; import android.view.View; import android
2022-06-06

Android中Handler实现倒计时的两种方式

背景:最近项目中,正好做到登录/注册这个功能块。它需要通过发送验证码,在规定的时间内用验证码来完成登录/注册。之前的项目中也有这个功能,但是觉得太复杂了,只好自己重新实现一遍。用Handler来做,觉得代码简介,逻辑也清楚。代码一://在向
2023-05-31

Android中Rxjava实现三级缓存的两种方式

本文正如标题所说的用rxjava实现数据的三级缓存分别为内存,磁盘,网络,刚好最近在看Android源码设计模式解析与实战(受里面的ImageLoader的设计启发)。我把代码放到了我的hot项目中,github地址 源码下载地址:Rxja
2022-06-06

PHP中间件模式的两种实现方法详解

PHP中间件模式实现了请求处理的拦截和修改,可分为两种实现方法:基于服务的中间件:使用服务提供者管理,适用于服务容器框架,灵活且可重用。基于路由的中间件:直接在路由中指定,适用于路由框架,简单且性能较高。根据框架和需求,选择适合的实现方法:服务容器框架优先基于服务的中间件。路由框架优先基于路由的中间件。
PHP中间件模式的两种实现方法详解
2024-04-02

uniapp中如何实现页面之间的引用(两种方法)

在Uniapp中,我们经常需要在一个页面中引用另一个页面的内容。这里我们介绍两种方法来实现页面之间的引用。方法一:使用页面路径我们可以使用页面路径来引入另一个页面,例如:```html<template> <view> <other-page></other-page> </view></template><script> import OtherPage from
2023-05-14

vue中Echarts使用动态数据的两种实现方式

这篇文章主要介绍了vue中Echarts使用动态数据的两种实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

Android中fragment与activity之间的交互(两种实现方式)

(未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文《详解Android中Fragment的两种创建方式》,就如何创建Fragment混合布局做了详细的分析,今
2022-06-06

Android:在service和activity之中,实现音乐播放进度条传递信息的两种方式

实现播放时的进度条显示,或是定时从service获取某些信息,是我们日常开发中经常遇到的需求,下面介绍当音乐再service中运行时,activity如果获取音乐进度信息的两种方式: 一、在activity中建立消息接收机制 我们需要在ac
2022-06-06

编程热搜

目录