如何把网站提交到百度/搜索引擎优化案例
在js中,我们通过new运算符来创建一个对象,它是一个高频的操作。我们一般只是去用它,而很少关注它是如何实现的,它的工作机制是什么。
1 简介
本文介绍new的功能,用法,补充介绍了不加new也同样创建对象的方式,分析了new的原理,最后模拟了new的实现。
学习本文内容需要你了解js中对象,原型链,call,bind,arguments的用法。
2.new 的基本用法
我们通过new来创建对象,它的基本格式是:
var 对象 = new 函数([参数])
这里的函数可以是内置构造器,也可以是用户自己定义的函数。
例如:
var arr = new Array ();
此时,arr将可以使用Array.prototype上的全部方法。
更一般的情况,我们会使用自己定义的构造器。
function F(name,age){
this.name = name;
this.age = age
}
F.prototype.hello = function(){
console.log(this.name,this.age)
}
var f1 = new F('curry', 30);
console.log(f1)
f1.hello()
对如上的代码有几点说明如下:
函数F
在被调用的过程中,在前面加 new ,所以这个函数是被当作
构造器来使用了。
f1
之所以可以调用 hello方法,也是因为原型链的缘故。
3 构造器的返回值
一般来讲,如果你要把一个函数当做构造函数来使用,在这个函数的内部是不应该
去设置返回值的。但是,如果它设置了返回值呢?
先说出答案如下:
return后面跟着不是对象,就会不管return语句,返回this对象;
return后面跟着一个对象,new会返回return语句指定的对象;
先来看构造器中,return后面跟着不是对象的情况。
var Vehicle = function () {
this.price = 1000;
return 1000;
};
(new Vehicle()) === 1000// false
上面代码中,构造函数Vehicle的return语句返回一个数值。这时,new命令就会忽略这个return语句,就当它不存在,还是正常返回“构造”后的this对象。
但是,如果return语句返回的是一个对象,new命令会返回这个新对象,而不再是this对象,这一点需要特别引起注意。
var Vehicle = function (){
this.price = 1000;
return { price: 2000 };
};
(new Vehicle()).price
// 2000
上面代码中,构造函数Vehicle的return语句,返回的是一个新对象。new命令会返回这个对象,而不是this对象。
4 不加new也能创建对象吗?
对上面的代码,我们稍微改一下,在使用构造器时,故意去掉new这个关键字。如下:
function F(name,age){
this.name = name;
this.age = age
}
var f1 = F('curry', 30); // 不加new
console.log(f1)
此时,我们把F当作一个普通的函数来调用,由于在函数F内部并没有明确写出return语句,所以f1的值是undefined。同时上面的代码还会有另一个隐藏的后果:在执行F时,由于this的值是指向window,所以上面的代码还会给window对象添加两个属性。如下:
那么问题来了,如何确保这个F
只能被用作构造器,而不能当作普通函数来用呢?
两种解决思路:
如果不加new就报错。
如果不加new就偷着给你加上。
4.1 构造函数内部使用严格模式
为了保证构造函数必须与new命令一起使用,一个解决办法是,构造函数内部使用严格模式,即第一行加上use strict。这样的话,一旦忘了使用new命令,直接调用构造函数就会报错。
function F(name,age){
'use strict'; // 这句新加的
this.name = name;
this.age = age
}
var f1 = F('curry', 30); // 不加new
console.log(f1)
上面的代码会报错,错误是Uncaught TypeError: Cannot set property 'name' of undefined
。因为在函数内部开启了严格模式之后,函数内部的this将不会默认指向window
,它的值会是undefined。
一旦代码报错了,相当于提醒你必须给加上new,你就自己给它加上吧。
4.2 自动加上new
还可以在构造函数内部判断,当前调用是否使用new命令,如果发现没有使用new,则直接返回一个实例对象。
function F(name,age){
// 如果没有用new,this就不会是F的实例
if (!(this instanceof F)) {
return new F(name,age);
}
this.name = name;
this.age = age
}
var f1 = new F('a','30');
var f2 = F('b','30');
console.log(f2)
上面代码中的构造函数,不管加不加new命令,都会得到同样的结果。如下:
5 new 原理
使用new命令时,在构造函数内部依次执行下面的步骤。
第一步:创建一个空对象,作为将要返回的对象。
第二步:将这个空对象的原型指向构造函数的prototype属性。这一步的作用是让这个对象能沿着原型链去使用构造函数中prototype上的方法。
第三步:将这个空对象赋值给构造函数内部的this关键字,执行构造函数。这一步的作用是让构造器中设置在this上的属性最终设置在这个对象上。
第四步:返回这个对象。
以如下代码为例:
function F(name,age){
this.name = name;
this.age = age
}
F.prototype.hello = function(){
console.log(this.name,this.age)
}
var f = new F('a','30');
则上面四步的伪代码如下:
第一步:var obj = {}
第二步:obj.__proto__ = F.prototype
第三步:F.apply(obj,参数)
第四步:return obj
下面模拟一下new的实现。由于new是一个关键字,我们写一个单独的函数_new来模拟,最终的目标是:
function F(name,age){
this.name = name;
this.age = age
}
F.prototype.hello = function(){
console.log(this.name,this.age)
}
// 使用模拟new,
var f1 = _new(F,'a',30);
// 希望达到与new F('a',30)一致的效果
f1.hello();
你可以先想一想, 如何实现_new哈。
下面是一个参考实现:
function _new(constructor, ...args) {// 创建一个新对象,将其原型设置为构造函数的原型const newObj = Object.create(constructor.prototype);// 调用构造函数,并将新对象作为上下文const result = constructor.apply(newObj, args);// 如果构造函数有显式返回一个对象,则返回该对象;否则,返回新对象return typeof result === 'object' && result !== null ? result : newObj;
}// 测试
function F(name, age) {this.name = name;this.age = age;
}F.prototype.hello = function() {console.log(this.name, this.age);
}var f1 = _new(F, 'a', 30);
f1.hello(); // 输出:a 30
代码解释:
// 创建一个新对象,将其原型设置为构造函数的原型const newObj = Object.create(constructor.prototype);// 等同于:const newObj = {}; // 创建一个空对象newObj.__proto__ = constructor.prototype; // 将新对象的原型设置为构造函数的原型// 调用构造函数,并将新对象作为上下文const result = constructor.apply(newObj, args);解释:当我们调用 `constructor.apply(newObj, args)` 时,我们将 `constructor` 构造函数作为函数调用,并将 `newObj` 对象作为其上下文。关于 `apply` 方法,它是 JavaScript 中用于调用函数的方法,可以设置函数调用时的上下文对象以及参数列表。它接收两个参数:上下文对象和参数数组。在这行代码中,我们将 `newObj` 对象作为上下文对象,这样在构造函数内部可以通过 `this` 来引用这个新创建的对象。然后,我们将 `args` 数组展开作为参数列表传递给构造函数。这样,构造函数就会在 `newObj` 对象的上下文中执行,从而将构造函数内部的属性和方法赋值给 `newObj` 对象。最后,我们的实现返回了这个新创建的对象,以便我们可以像使用 `new` 关键字一样访问该对象的属性和方法。
版权信息:凡人进阶。
相关文章:

javascript中的new原理及实现
在js中,我们通过new运算符来创建一个对象,它是一个高频的操作。我们一般只是去用它,而很少关注它是如何实现的,它的工作机制是什么。 1 简介 本文介绍new的功能,用法,补充介绍了不加new也同样创建对象的方…...

R语言 PPT 预习+复习
什么狗吧发明的结业考,站出来和我对线 第一章 绪论 吊码没有,就算考R语言特点我也不背,问就是叫么这没用。 第二章 R语言入门 x<-1:20 赋值语句 x 1到20在x上添加均值为0、标准差为2的正态分布噪声 y <- x rnorm (20, 0, 2) 这…...

轻松实现固定资产智能管理的工具来了
易点易动资产管理系统是一款旨在轻松实现智能资产管理的工具。固定资产管理对于企业的日常经营和可持续发展至关重要。然而,固定资产具有设备价值高、使用周期长、使用地点分散、使用环境恶劣、流动性强、安全管理难度大等特点,传统的管理方式往往无法高…...

软考高级系统架构设计师系列之:微服务
软考高级系统架构设计师系列之:微服务 一、微服务二、微服务的优势三、微服务挑战四、微服务与SOA的对比一、微服务 微服务架构建议将大型复杂的单体架构应用划分为一组微小的服务,每个微服务根据其负责的具体业务职责提炼为单一的业务能力。每个服务可以很容易地部署并发布…...

vue + axios + mock
参考来源:Vue mock.js模拟数据实现首页导航与左侧菜单功能_vue.js_AB教程网 记录步骤:在参考资料来源添加axios步骤 1、安装mock依赖 npm install mock -D //只在开发环境使用 下载完成后,项目文件package.json中的devDependencies就会加…...

Mongoose 开源库--json 使用笔记
一、 json相关API mongoose 开源库可以使用json进行数据处理。 ①创建json字符串 // A helper macro for printing JSON: mg_snprintf(buf, len, "%m", MG_ESC("hi")) #define MG_ESC(str) mg_print_esc, 0, (str) char *mg_mprintf(const char *fmt, ...)…...

linux中复制文件如何排除一个目录
误区: 首先使用cp命令的 --exclude参数实不可取的,会造成以下的报错,因为cp命令中压根就没有--exclude这个参数的配置 cp: unrecognized option --exclude‘****’ 问题解决: 我们可以使用rsync工具来完成目录排除的功能&#x…...

时空智友企业信息管理系统任意文件读取漏洞复现
简介 时空智友企业信息管理系统是一个用于企业流程管理和控制的软件系统。它旨在帮助企业实现流程的规范化、自动化和优化,从而提高工作效率、降低成本并提升管理水平。 时空智友企业信息管理系统存在任意文件读取漏洞,攻击者可以在未授权的情况下读取…...

YOLOv8优化:block系列篇 | Neck系列篇 |可重参化EfficientRepBiPAN优化Neck
🚀🚀🚀本文改进: 可重参化EfficientRepBiPAN优化Neck 如何在YOLOv8下使用:1)结合neck; 🚀🚀🚀EfficientRepBiPAN在各个领域都有ying 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研; 1.原理…...

零代码编程:用ChatGPT批量提取flash动画swf文件中的mp3
文件夹:C:\迅雷下载\有声绘本_flash[淘宝-珍奥下载]\有声绘本 flash,里面有多个flash文件,怎么转换成mp3文件呢? 可以使用swfextract工具从Flash动画中提取音频,下载地址是http://www.swftools.org/download.html,也…...

2023数学建模国赛C题赛后总结
今天国赛的成绩终于出来了,盼星星盼月亮的。之前面试的时候已经把我给推到国奖评委那里去了,可是好可惜,最终以很微小的劣势错失国二。只拿到了广西区的省一。我心里还是很遗憾的,我真的为此准备了很久,虽然当中也有着…...

hiveSQL语法及练习题整理(mysql)
目录 hiveSQL练习题整理: 第一题 第二题 第三题 第四题 第五题 第六题 第七题 第八题 第九题 第十题 第十一题 第十二题 hivesql常用函数: hiveSQL常用操作语句(mysql) hiveSQL练习题整理: 第一题 我…...

【UE4】UE编辑器乱码问题
环境:UE4.27、vs2019 如何解决 问题原因,UE的编码默认是UTF-8,VS的默认编码是GBK 通过"高级保存选项" 直接修改VS的 .h头文件 的 编码 为 UTF-8 步骤1. 步骤2. 修改编码后,从新编译,然后就可以解决编辑器…...

2 创建svelte项目(应用程序)
官网方式搭建: npm create sveltelatest my-app cd my-app npm install npm run dev 官网中介绍: 如果您使用的是 VS Code,安装 Svelte for VS Code 就可以了,以便语法高亮显示。 然后,一旦您的项目设置好了&#…...

手机怎么打包?三个方法随心选!
有的时候,电脑不在身边,只有随身携带的手机,这个时候又急需把文件打包发送给同事或者同学,如何利用手机操作呢?下面介绍了具体的操作步骤。 一、通过手机文件管理自带压缩功能打包 1、如果是iOS系统,就在手…...

SecureFX如何用Public key 連接sftp
點擊connection 右鍵點開站點的properties 點選SSH2--Authentication---Pulickey 先選擇Putty Key Generator save出來的public key(.pub)文件(Putty Key Generator 保存時可能沒加.pub後綴保存,可自行對public key加上後綴.pub) 同時注意要…...

BUUCTF 隐藏的钥匙 1
BUUCTF:https://buuoj.cn/challenges 题目描述: 路飞一行人千辛万苦来到了伟大航道的终点,找到了传说中的One piece,但是需要钥匙才能打开One Piece大门,钥匙就隐藏在下面的图片中,聪明的你能帮路飞拿到钥匙ÿ…...

idea使用gradle教程 (idea gradle springboot)2024
这里白眉大叔,写一下我工作时候idea怎么使用gradle的实战步骤吧 ----windows 环境----------- 1-本机安装gradle 环境 (1)下载gradle Gradle需要JDK的支持,安装Gradle之前需要提前安装JDK8及以上版本 https://downloads.gra…...

本地部署 lama-cleaner
本地部署 lama-cleaner 什么是 lama-cleanerGithub 地址部署 lama-cleaner启动 lama-cleaner 什么是 lama-cleaner lama-cleaner 是一款由 SOTA AI 模型提供支持的免费开源修复工具。 从照片中删除任何不需要的物体、缺陷、人物,或擦除并替换(由稳定扩…...

供应链云仓系统:实现采购、销售、收银、路线规划一体化,高效协同,再创商业价值!
供应链云仓系统是一款集合采购、销售、收银、路线规划等多项功能的软件系统,旨在帮助企业实现业务流程的全面自动化和协同化。通过该系统,企业可以轻松管理供应链的各个环节,提高运营效率,降低成本,实现商业价值的最大…...

如何用devtools快速开发一个R语言包?
如何用devtools快速开发一个R语言包? 1. 准备工作2. 如何完整开发一个R包3. 初始化新包4. 启用Git仓库5. 按照目标实现一个函数6. 在.R文件夹下创建文件并保存代码7. 函数测试8. 阶段性总结9. 时不时地检查完整工作状态10. 编辑DESCRIPTION文件11. 配置许可证12. 配…...

1、Sentinel基本应用限流规则(1)
Sentinel基本应用&限流规则 1.1 概述与作用 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。缓存、降级和限流是保护微服务系统运行稳定性的三大利器。 缓存:提升系统访问速度和增大系统能处理的容量 降级:当服务出问题或者影…...

BitBucket 进行代码管理
目的&原因 小团队代码管理,BitBucket 提供免费代码仓库。 创建代码仓库&邀请团队 注册&创建 group(workspace) 可创建私有通过邮箱 invite 团队成员 创建仓库 要选择所属的 workspace 和 project(没有可同时创建&…...

惊艳!拓世法宝AI智能数字人一体机解锁数字文博的全民体验
在数字化的潮流中,我们见证了历史与现代技术的完美融合。在今年的“国际古迹遗址日”,世界首个超时空参与式博物馆“数字藏经洞”正式与公众见面,在这里开启了一场前所未有的文化探索之旅。 时间和空间被艺术化的数字技术巧妙地折叠…...

Redis之与SSM集成Spring注解式缓存
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《Redis实战开发》。🎯🎯 …...

Android 安卓 Soong构建系统——Blueprint Android.bp配置文件解析
文章目录 Android.bp起源Android.bp文件结构如何编写Android.bp文件实例详解实例1实例2 常见问题解答1. 如何确定使用哪种模块类型?2. 如何指定模块的依赖项?其他疑问可参考官方文档 参考文章:Android.bp 语法和使用 Android.bp起源 早期的A…...

【Redis】SSM整合Redis注解式缓存的使用
【Redis】SSM整合Redis&注解式缓存的使用 一、SSM整合Redis1.2.配置文件spring-redis.xml1.3.修改applicationContext.xml1.4.配置redis的key生成策略 二、Redis的注解式开发及应用场景2.1.什么是Redis注解式2.实列测试 三、Redis中的击穿、穿透、雪崩的三种场景 一、SSM整…...

lua中的循环 while、for、repeat until三种循环方式、pairs和ipairs区别
lua中的循环 while、for、repeat until三种循环方式、pairs和ipairs区别 介绍for循环参数ipairs和pairs whilerepeat until总结 介绍 这里我用while、for、repeat until分别输出1-20之间的奇数 ,具体的语法可以看下面的代码 for循环 参数 定义一个初始值为start…...

Linux 进程的管道通信
文章目录 无名管道pipe有名管道 进程之间的通信:Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都看不到,所以进程之间不能相互访问,要交换数据必须通过…...

OpenGL和Vulkan比较
比较 见参考 参考 Reference GuidesCopyright 2022-2023 The Khronos Group Inc. :: Vulkan Documentation ProjectDifference Between OpenGL vs VulkanVulkan与OpenGL对比——Vulkan的全新渲染架构 图形程序接口:OpenGL、OpenCL、Vulkan、OpenGL ES、WebGL…...