深入理解JavaScript之 new 原理及模拟实现
时间:2020-11-21
本文章向大家介绍深入理解JavaScript之 new 原理及模拟实现,主要包括深入理解JavaScript之 new 原理及模拟实现使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1.定义
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例
先看看 new 实现了哪些功能, 先来看一段代码:
function Person(age) {
this.age = age;
}
Person.prototype.getAge = function() {
console.log("年龄为:" + this.age );
}
var person = new Person(18);
person.age; // 访问构造函数里的属性
// 18
person.getAge(); // 访问原型里的属性
// 年龄为:18
从上面代码可以知道,实例 person 可以:
- 访问到 Person 构造函数里的属性
- 访问到 Person.prototype 中的属性
这个是最基本的了,也是刚学会new一个对象就知道这是new的特点
2.探讨new还做了什么?
探讨完上面,接下来看看new还做了什么?来看几个例子
1. 没有return语句
function Person(age) {
this.age = age;
}
var person = new Person(18);
console.log(person); // Person {age: 18}
从构造函数直观看,最后是没有 return语句的,但我们从返回结果也可以看出构造函数时默认情况会返回一个新对象
2. return 对象数据类型
我们尝试在构造函数最后返回一个对象
function Person(age) {
this.age = age;
return { name: '手动返回一个对象' }
}
var person = new Person(18);
console.log(person); // {name: "手动返回一个对象"}
打印出来的结果可以看书:return 之前的代码片段都被覆盖了,最后返回 return 后面的对象。
3. return 基本数据类型
如果构造函数最后return的不是对象呢,试下基本数据类型
function Person(age) {
this.age = age;
return 1
}
var person = new Person(18);
console.log(person); // Person {age: 18}
从打印出来的结果可知,和没有return效果一样。
3.new原理
mdn上把内部操作大概分为4步:
- 创建一个空的简单JavaScript对象(即{ } );
- 链接该对象(即设置该对象的构造函数)到另一个对象 ;(因此this就指向了这个新对象)
- 执行构造函数中的代码(为这个新对象添加属性);
- 如果该函数没有返回对象,则返回this。
广州品牌设计公司https://www.houdianzi.com
5.模拟实现new
new 是关键词,不可以直接覆盖。这里使用 create 来模拟实现 new 的效果。
function myNew() {
// 创建一个空的对象
var obj = new Object(),
// 获得构造函数,arguments中去除第一个参数
Con = [].shift.call(arguments);
// 链接到原型,obj 可以访问到构造函数原型中的属性
obj.__proto__ = Con.prototype;
// 绑定 this 实现继承,obj 可以访问到构造函数中的属性
var ret = Con.apply(obj, arguments);
// 优先返回构造函数返回的对象
return ret instanceof Object ? ret : obj;
};
来看看上面是怎么一步步模拟实现的:
- 用new Object() 的方式新建了一个空对象 obj
- 取出第一个参数,即是传入的构造函数。shift 会修改原数组,数组原来的第一个元素的值。
- 将 obj 的原型指向构造函数,这样 obj 就可以访问到构造函数原型中的属性
- 使用 apply,改变构造函数 this 的指向。将this指向obj对象 就可以访问到构造函数中的属性
- 处理返回值。
- 构造函数返回值有三种情况:
- 没有return,默认返回之前创建的对象
- 返回一个对象
- 返回的不是对象,默认返回之前创建的空对象
在上面我们用instanceof方法来判断是否为对象
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
测试:
function Person(age) {
this.age = age;
}
Person.prototype.getAge = function() {
console.log("年龄为:" + this.age );
}
var person = create(Person, 18)
person.age; // 访问构造函数里的属性
// 18
person.getAge(); // 访问原型里的属性
// 年龄为:18
模拟实现成功!
原文地址:https://www.cnblogs.com/xiaonian8/p/14017571.html
- 初识ListView
- 响应Android系统的事件
- ImageSwitcher和TextSwitcher
- Android BLE 基础框架全新改版
- Android 混淆从入门到精通
- 基础篇章:关于 React Native 之 ViewPagerAndroid 组件的讲解
- 基础篇章:关于 React Native 之 DrawerLayoutAndroid 组件的讲解
- Android 使用 ApachePOI 组件读写 Word doc 和 docx 文件
- Android 开发中如何动态加载 so 库文件
- 良心推荐:总结 Android 开发中必备的代码 Review 清单
- 强烈推荐:基于Java反射实现一个 Android ORM 框架
- Android 高效安全的本地广播 LocalBroadcast 完全解析
- Android的编译打包流程详解
- Android 仿京东、拼多多商品分类页
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 全栈必备 Redis基础
- JSP的异常处理
- (二)Mybatis-Plus的安装配置
- 如何在JSP里自定义标签
- 如何在JSP里使用Java bean
- 获取指定时间内指定星期几的所有日期
- 使用JSP的标准标签库JSTL处理XML格式的数据
- (一)初识Mybatis-Plus
- org.apache.tomcat.util.scan.StandardJarScanner找不到serializer.jar的问题
- JAVA中获取当前系统时间
- 使用Supervisor管理进程
- vue 中使用threejs
- 数据库COUNT(*)、COUNT(字段)和COUNT(1)的异同
- 生成项目目录树
- 几行代码搞定智能插座控制丨云开发 × 涂鸦