不得不看之JavaScript构造函数及new运算符
发布时间 - 2026-01-11 02:54:01 点击率:次JS中的函数即可以是构造函数又可以当作普通函数来调用,当使用new来创建对象时,对应的函数就是构造函数,通过对象来调用时就是普通函数。

普通函数的创建有:显式声明、匿名定义、new Function() 等三种方式。
当通过new来创建一个新对象时,JS底层将新对象的原型链指向了构造函数的原型对象,于是就在新对象和函数对象之间建立了一条原型链,通过新对象可以访问到函数对象原型prototype中的方法和属性。
和其他高级语言一样 Javascript 中也有构造函数和 new 运算符,我们知道 new 是用来实例化一个类,从而在内存中分配一个实例对象。 但在 Javascript 中,万物皆对象,为什么还要通过 new 来产生对象? 本文将带你一起来探索 Javascript 中 new 的奥秘…
1、认识new运算符
function Animal(name){
this.name = name;
}
Animal.color = "black";
Animal.prototype.say = function(){
console.log("I'm " + this.name);
};
var cat = new Animal("cat");
console.log(
cat.name, //cat
cat.color //undefined
);
cat.say(); //I'm cat
console.log(
Animal.name, //Animal
Animal.color //back
);
Animal.say(); //Animal.say is not a function
2、代码解读
1-3行创建了一个函数Animal,并在其this上定义了属性:name,name的值是函数被执行时的形参。
第4行在Animal对象(Animal本身是一个函数对象)上定义了一个静态属性:color,并赋值“black”
5-7行在Animal函数的原型对象prototype上定义了一个say()方法,say方法输出了this的name值。
第8行通过new关键字创建了一个新对象cat
10-14行cat对象尝试访问name和color属性,并调用say方法。
16-20行Animal对象尝试访问name和color属性,并调用say方法。
3、重点解析
第8行代码是关键:
var cat = new Animal("cat");
Animal 本身是一个普通函数,但当通过new来创建对象时,Animal就是构造函数。
JS引擎执行这句代码时,在内部做了很多工作,用伪代码模拟其工作流程如下:
new Animal("cat") = {
var obj = {};
obj.__proto__ = Animal.prototype;
var result = Animal.call(obj,"cat");
return typeof result === 'object'? result : obj;
}
(1)创建一个空对象obj;
(2)把obj的proto指向构造函数Animal的原型对象prototype,此时便建立了obj对象的原型链:obj->Animal.prototype->Object.prototype->null
(3)在obj对象的执行环境调用Animal 函数并传递参数“cat”。 相当于var result = obj.Animal(“cat”)。
(4)考察第3步返回的返回值,如果无返回值或者返回一个非对象值,则将obj返回作为新对象;否则会将返回值作为新对象返回。
理解了其运行机制以后,我们知道cat其实就是过程(4)的返回值,因此我们对cat对象的认知就多了一些:
cat的原型链是:cat->Animal.prototype->Object.prototype->null
cat上新增了一个属性:name
分析完了cat的产生过程,我们再看看输出结果:
cat.name -> 在过程(3)中,obj对象就产生了name属性。因此cat.name就是这里的obj.name
cat.color -> cat会先查找自身的color,没有找到便会沿着原型链查找,在上述例子中,我们仅在Animal对象上定义了color,并没有在其原型链上定义,因此找不到。
cat.say -> cat会先查找自身的say方法,没有找到便会沿着原型链查找,在上述例子中,我们在Animal的prototype上定义了say,因此在原型链上找到了say方法。
另外,在say方法中还访问this.name,这里的this指的是其调用者obj,因此输出的是obj.name的值。
对于Animal来说,它本身也是一个对象,因此,它在访问属性和方法时也遵守上述查找规则,所以:
Animal.color -> “black”
Animal.name -> “Animal” , Animal先查找自身的name,找到了name, 但这个name不是我们定义的name,而是函数对象内置的属性。
一般情况下,函数对象在产生时会内置name属性并将函数名作为赋值(仅函数对象)。
Animal.say -> Animal在自身没有找到say方法,也会沿着其原型链查找,话说Animal的原型链是什么呢?
从测试结果看:Animal的原型链是这样的:
Animal->Function.prototype->Object.prototype->null
因此Animal的原型链上没有定义say方法!
4、new存在的意义
认识了new运算符之后,我们再回到开篇提到的问题:JS中万物皆对象,为什么还要通过new来产生对象?
要弄明白这个问题,我们首先要搞清楚cat和Animal的关系:
通过上面的分析,我们发现cat继承了Animal中的部分属性,因此我们可以简单的理解:Animal和cat是继承关系。
另一方面,cat是通过new产生的对象,那么cat到底是不是Animal的实例对象? 我们先来了解一下JS是如何来定义“实例对象”的?
A instanceof B
如果上述表达式为true,JS认为A是B的实例对象,我们用这个方法来判断一下cat和Animal
cat instanceof Animal; //true
从执行结果看:cat确实是Animal实例,要想证实这个结果,我们再来了解一下JS中instanceof的判断规则:
var L = A.__proto__; var R = B.prototype; if(L === R) return true;
如果A的proto 等价于 B的prototype,就返回true
在new的执行过程(2)中,cat的proto指向了Animal的prototype,所以cat和Animal符合instanceof的判断结果。
因此,我们认为:cat 是Animal的实例对象。
5、总结
在Javascript中, 通过new可以产生原对象的一个实例对象,而这个实例对象继承了原对象的属性和方法。因此,new存在的意义在于它实现了Javascript中的继承,而不仅仅是实例化了一个对象!
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助~如果有疑问大家可以留言交流,谢谢大家对的支持!
# JS
# 构造函数
# new运算符
# 关于Js中new操作符的作用详解
# Javascript模拟实现new原理解析
# 浅析JS中NEW的实现原理及重写
# JS使用new操作符创建对象的方法分析
# JavaScript中的 new 命令
# JS重学系列之聊聊new操作符
# 原生JS封装_new函数实现new关键字的功能
# JavaScript new对象的四个过程实例浅析
# 如何自己实现JavaScript的new操作符
# 返回值
# 是一个
# 没有找到
# 运算符
# 便会
# 创建一个
# 会先
# 的是
# 建立了
# 找到了
# 也有
# 就在
# 也会
# 是这样
# 找不到
# 但在
# 继承了
# 并在
# 这个问题
# 我们可以
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
北京的网站制作公司有哪些,哪个视频网站最好?
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
想要更高端的建设网站,这些原则一定要坚持!
JavaScript中如何操作剪贴板_ClipboardAPI怎么用
Laravel如何生成PDF或Excel文件_Laravel文档导出工具与使用教程
如何破解联通资金短缺导致的基站建设难题?
如何快速搭建个人网站并优化SEO?
如何在阿里云服务器自主搭建网站?
焦点电影公司作品,电影焦点结局是什么?
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理
laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程
浅述节点的创建及常见功能的实现
Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录
高防服务器租用指南:配置选择与快速部署攻略
Laravel API资源类怎么用_Laravel API Resource数据转换
JavaScript如何实现类型判断_typeof和instanceof有什么区别
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
如何正确下载安装西数主机建站助手?
Laravel如何使用查询构建器?(Query Builder高级用法)
JavaScript中的标签模板是什么_它如何扩展字符串功能
Laravel如何实现本地化和多语言支持?(i18n教程)
移动端脚本框架Hammer.js
Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】
Laravel如何使用Service Container和依赖注入?(代码示例)
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验
微信小程序 input输入框控件详解及实例(多种示例)
装修招标网站设计制作流程,装修招标流程?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】
Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧
Laravel如何使用模型观察者?(Observer代码示例)
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
如何在腾讯云服务器快速搭建个人网站?
MySQL查询结果复制到新表的方法(更新、插入)
敲碗10年!Mac系列传将迎来「触控与联网」双革新
bootstrap日历插件datetimepicker使用方法
成都网站制作公司哪家好,四川省职工服务网是做什么用?
php结合redis实现高并发下的抢购、秒杀功能的实例
长沙企业网站制作哪家好,长沙水业集团官方网站?
如何挑选最适合建站的高性能VPS主机?
如何快速上传自定义模板至建站之星?
详解CentOS6.5 安装 MySQL5.1.71的方法
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】

