1、Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

var _this = Object.create(fn.prototype);这句代码的意思是fn的prototype属性内容作为新对象的原型内容。

2、apply方法会改变this的指向。原本fn函数中调用时,也就是这样fn(),this指向的是window,但是这样使用之后fn.apply(_this, args); _this指向的是上面新创建的对象,所以改变了fn中this的指向,新对象也就有拥有了fn中的属性 。可以理解为新对象继承了fn中的属性。args是参数,必须是数组的形式,name和age属性也就有了值。

3、return中是一个三元运算,res是否存在,如果存在就返回,不存在就返回_this 。

实例化对象有一个属性叫做__proto__(原型),构造函数上有一个属性叫做prototype(原型对象)。在构造函数实例化的时候,构造函数会把prototype上面的方法和属性,复制到实例化对象的__proto__上。所以实例化对象,继承了构造函数原型上的方法和属性。

一个函数只有通过new实例化之后,才叫做构造函数。

若构造函数中没有返回值或返回值是基本类型(Number、String、Boolean)的值,则返回新实例对象;若返回值是引用类型的值,则实际返回值为这个引用类型。

apply方法会改变this的指向。原本fn函数调用时,也就是fn()这种写法,this指向的是window,但是fn.apply(_this, args)这种写法 _this指向的是上面新创建的对象,所以改变了fn中this的指向,新对象也就有拥有了fn中的属性 。可以理解为新对象继承了fn中的属性。args是参数,必须是数组的形式,name和age属性也就有了值。

            //当使用new关键字去调用那个函数的时候,那这个函数就会被作为构造函数去进行调用,然后它会走构造函数的一套流程去执行这么一个函数
//在这里调用构造函数的样子跟其他语言去实例化一个类的方式也很像,都是使用new关键字,所以很容易造成混淆
//推荐写class //在js中创建一个对象的方式是很多的,构造函数也是其中的一种方式
// const obj = {}
// new Object();
// Object.create(); //使用new关键字调用一个函数,这个函数就会被当做构造函数进行调用
function Person(name,age){
this.name = name;
this.age = age;
}
//如果它没有返回值就会返回出一个对象
//不妨思考一下返回的对象是怎么出现的,为什么它上面有张三跟11
const p =new Person('张三',11)
console.log(p)
//p.__proto__是等于Person.prototype,这也证明了第二步,把构造函数的prototype属性作为空对象的原型。 console.log(p.__proto__ == Person.prototype) //true




            //当用new关键字调用函数的时候,发生了什么,为什么会获得一个新的对象

            // 1.创建一个空的对象
// 2.把构造函数的prototype属性(Person.prototype) 作为空对象的原型,这样空对象就可以访问到Person.prototype上面的方法了
// 3.this赋值为这个空对象
// 4.执行函数
// 5.如果函数没有返回值,则返回this(也可以说是返回之前那个空对象) //把一个函数变成构造函数:
function Constructor(fn,args){
//fn表示要作为构造函数的函数,args表示要调用fn这个构造函数时需要传递给它的一些参数 //1.创建空对象
var _this = Object.create(fn.prototype); //以fn.prototype为原型创建的一个空对象 //第一个参数表示fn函数内部的this指向的对象,第二个参数是传入fn函数的参数 //fn函数是window对象调用的,所以this指向的是window ,然后使用apply方法,改变this指向创建的Person 对象。
var res = fn.apply(_this, args);
console.log(res) //输出undefined,为什么? //如果有res就返回res,如果没有就返回创建的对象
return res ? res : _this;
} function Person1(name,age){
this.name = name;
this.age = age;
}
Person1.prototype.say = function(){
console.log('我叫' + this.name);
} var person = Constructor(Person1, ['李四',21])
console.log(person)


在ES5中模拟类的更多相关文章

  1. Es5中的类和静态方法 继承

    Es5中的类和静态方法 继承(原型链继承.对象冒充继承.原型链+对象冒充组合继承) // es5里面的类 //1.最简单的类 // function Person(){ // this.name='张 ...

  2. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  3. ES5中的类与继承

    最近在重新复习TypeScript,看到类这块的时候自然会和ES5中的类写法进行对比加深印象. 发现ES5的类与继承一些细节还是挺多的,时间久了容易忘记,特此记录下. 首先是ES5的类定义,这没什么好 ...

  4. ES5中的类

    之前小编对于类和类的基本特征(所谓的封装.继承.多态)理解一直不是很到位,同时在实际项目应用中也用的比较少,今天小编就结合ES5中的基本用法和大家聊聊,希望小伙伴会在这篇文章有属于自己的收获,并能够在 ...

  5. Typescript中的类 Es5中的类和静态方法和继承(原型链继承、对象冒充继承、原型链+对象冒充组合继承)

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...

  6. ES6中的类

    前面的话 大多数面向对象的编程语言都支持类和类继承的特性,而JS却不支持这些特性,只能通过其他方法定义并关联多个相似的对象,这种状态一直延续到了ES5.由于类似的库层出不穷,最终还是在ECMAScri ...

  7. koa 基础(十七)原生 JS 中的类、静态方法、继承

    1.app.js /** * 原生 JS 中的类.静态方法.继承 * es5中的类和静态方法 */ function Person(name, age) { // 构造函数里面的方法和属性 this. ...

  8. 《深入理解ES6》笔记—— JavaScript中的类class(9)

    ES5中的近类结构 ES5以及之前的版本,没有类的概念,但是聪明的JavaScript开发者,为了实现面向对象,创建了特殊的近类结构. ES5中创建类的方法:新建一个构造函数,定义一个方法并且赋值给构 ...

  9. 在 JavaScript 中使用构造器函数模拟类

    今天,我们要讲的是在 JavaScript 中使用构造器函数(construcor function)模拟类. 构造器函数简介 你可以使用 ES6 的 class 关键字来实现类,不过我建议你使用传统 ...

随机推荐

  1. python的模拟算法--打印任务

    模拟算法:打印任务 Queue来实现 队列(queue)是一种有次序的数据集合,其特征是新数据项的添加总发生在一端(通常称为"尾rear"端)而现存数据项的移除总发生在另一端(通常 ...

  2. 第十五篇 -- QListWidget与QToolButton(界面)

    效果图: 这还只是一个界面,并没有实现相应功能. 先看下这图的构成吧. 工具栏的就是将Action拖上去,这部分前面已经介绍过了,那就看下面这部分的构图. 1.左侧是一个工具箱(ToolBox)组件, ...

  3. [SqlServer] 理解数据库中的数据页结构

    这边文章,我将会带你深入分析数据库中 数据页 的结构.通过这篇文章的学习,你将掌握如下知识点: 1. 查看一个 表/索引 占用了多少了页. 2. 查看某一页中存储了什么的数据. 3. 验证在数据库中用 ...

  4. php 获取上个月的起止时间戳

    $thismonth = date('m'); $thisyear = date('Y'); if ($thismonth == 1) { $lastmonth = 12; $lastyear = $ ...

  5. 深度强化学习中稀疏奖励问题Sparse Reward

    Sparse Reward 推荐资料 <深度强化学习中稀疏奖励问题研究综述>1 李宏毅深度强化学习Sparse Reward4 ​ 强化学习算法在被引入深度神经网络后,对大量样本的需求更加 ...

  6. Scrapy入门到放弃04:下载器中间件,让爬虫更完美

    前言 MiddleWare,顾名思义,中间件.主要处理请求(例如添加代理IP.添加请求头等)和处理响应 本篇文章主要讲述下载器中间件的概念,以及如何使用中间件和自定义中间件. MiddleWare分类 ...

  7. 使用jwt来保护你的接口服务

    以前写过一篇关于接口服务规范的文章,原文在此,里面关于安全性问题重点讲述了通过appid,appkey,timestamp,nonce以及sign来获取token,使用token来保障接口服务的安全. ...

  8. 这才是做了五年Android开发该有的样子!

    程序员工作五年后一般怎样了? 五年程序员生涯对身体上的摧残就不说了,来讲讲一般会有怎样的状态吧! 优秀的一般是这样:有着明确的职业目标与规划,热爱技术,五年的工作沉淀,技术能力得到了飞速提升,每天依然 ...

  9. 史上最详细的Android消息机制源码解析

    本人只是Android菜鸡一个,写技术文章只是为了总结自己最近学习到的知识,从来不敢为人师,如果里面有不正确的地方请大家尽情指出,谢谢! 606页Android最新面试题含答案,有兴趣可以点击获取. ...

  10. C++实现链表的相关基础操作

    链表的相关基础操作 # include <iostream> using namespace std; typedef struct LNode { int data; //结点的数据域 ...