手动实现一个new操作

2018-06-14 admin

写在前面


在所有的前端面试中常常喜欢考面试者如何手写一个new操作符,作为在准备秋招的大三党,我也要考虑这些。 那么我们先看看new操作符都干了什么事情,有哪些操作?通过下面的代码来进行思考:

// 新建一个类(构造函数)
function Otaku(name, age) {
    this.name = name;
    this.age = age;
    // 自身的属性
    this.habit = 'pk';
}
// 给类的原型上添加属性和方法
Otaku.prototype.strength = 60;
Otaku.prototype.sayYourName = function () {
    console.log('I am ' + this.name);
}
// 实例化一个person对象
const person = new Otaku('乔峰',5000);
person.sayYourName();
console.log(person);//打印出构造出来的实例

控制台打印结果

解析

从控制台打印出来的结果我们可以看出new操作符大概做了几件事情:

  1. 返回(产生)了一个新的对象
  2. 访问到了类Otaku构造函数里的属性
  3. 访问到Otaku原型上的属性和方法 并且设置了this的指向(指向新生成的实例对象)

通过上面的分析展示,可以知道new团伙里面一定有Object的参与,不然对象的产生就有点说不清了。 先来边写写:

// 需要返回一个对象 借助函数来实现new操作 
// 传入需要的参数: 类 + 属性
const person = new Otaku('乔峰',5000);
const person1 = objectFactory(Otaku, '鸠摩智', 5000);

// 开始来实现objectFactory 方法 
function objectFactory(obj, name, age) {}
// 这种方法将自身写死了 如此他只能构造以obj为原型,并且只有name 和 age 属性的 obj
// 在js中 函数因为arguments 使得函数参数的写法异常灵活,在函数内部可以通过arguments来获得函数的参数
function objectFactory() {
    console.log(arguements); //{ '0': [Function: Otaku], '1': '鸠摩智', '2': 5000 }
     // 通过arguments类数组打印出的结果,我们可以看到其中包含了构造函数以及我们调用objectfactory时传入的其他参数
    // 接下来就是要想如何得到其中这个构造函数和其他的参数
    // 由于arguments是类数组,没有直接的方法可以供其使用,我们可以有以下两种方法:
    // 1\. Array.from(arguments).shift(); //转换成数组 使用数组的方法shift将第一项弹出
    // 2.[].shift().call(arguments); // 通过call() 让arguments能够借用shift方法
    const Constructor = [].shift.call(arguments);
    const args = arguments;
    // 新建一个空对象 纯洁无邪
    let obj = new Object();
    // 接下来的想法 给obj这个新生对象的原型指向它的构造函数的原型  
    // 给构造函数传入属性,注意:构造函数的this属性
    // 参数传进Constructor对obj的属性赋值,this要指向obj对象
    // 在Coustructor内部手动指定函数执行时的this 使用call、apply实现
    Constructor.call(obj,...args);
    return obj;
}

    function objectFactory() {
        let Constructor = [].shift.call(arguments);
        const obj = new Object();
        obj.__proto__ = Conctructor.prototype;
        Constructor.call(obj,...arguments);
        return obj;
    }
function myNew(Obj,...args){
  var obj = Object.create(Obj.prototype);//使用指定的原型对象及其属性去创建一个新的对象
  Obj.apply(obj,args); // 绑定 this 到obj, 设置 obj 的属性
  return obj; // 返回实例
}

原文链接:https://segmentfault.com/a/1190000015276659

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-33998.html

文章标题:手动实现一个new操作

相关文章
vue.js实现请求数据的方法示例
vue2.0示例代码如下: var vm = new Vue({ el:"#list", data:{ gridData: "", }, ...
2017-03-20
jQuery中DOM树操作之复制元素的方法
本文实例讲述了jQuery中DOM树操作之复制元素的方法。分享给大家供大家参考。具体分析如下: 复制元素 前面提到的操作包括:插人新创建的元素、将元素从文档中的一个位置移动 到另一个位置,以及通过新元素来包装已有的元素。可是,有时候也会用到...
2015-11-13
HTML5会是下一个风口吗?
2014年10月底, W3C(万维网联盟)正式宣布HTML5正式定稿,科技圈就像发现了可以打破谷歌、苹果所统领的原生APP世界的方法,发表了很多宣讲HTML5将真正开始颠覆原生(Native)App的文章,也开始着力发展HTML5,开始抢占...
2015-11-12
vuejs通过filterBy、orderBy实现搜索筛选、降序排序数据
直接贴代码了: 先上输入前的样子: <style> #example{margin:100px auto;width:600px;} .show{margin:10px;} #searchText{display: block...
2017-03-17
js实现鼠标左右移动,图片也跟着移动效果
效果:鼠标往左移,图片对应右移,鼠标往右移,图片就左移动。图片距离越远偏移距离越大。 思路:首先获取图片原先的距离。设置一个变化值,图片的最终距离等于原先的距离加上变化值 布局:大盒子里面是图片,大盒子position:relative;图...
2017-02-17
js实现文字向上轮播功能
话不多说,请看实现代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">...
2017-03-10
2015年2月国内操作系统市场份额概况,xp占46.29%,
规则调整:2012年6月1日开始,Mac操作系统中不再包含ipad、iphone市场份额。 ...
2015-11-12
纯css实现窗户玻璃雨滴逼真效果
这里仅是用CSS技术来演示这样的一个场景,可能并不太实用。然而这是一个探索CSS新功能的最佳机会。可以让你尝试使用一些新特性和新工具。并且逐渐将在工作中实践。在制作窗口雨滴效果,将使用到HAML和Sass。 案例效果 看到上面的效果是不是...
2017-03-29
canvas实现流星雨的背景效果
看到一个很棒的流星雨效果。修改一下样式就可以作为网页背景了。。! <!DOCTYPE html> <html> <head> <meta charset="utf-8&quot...
2017-03-09
js实现的tab标签切换效果代码分享
这是一款基于js实现的tab标签切换效果,是一款无需jQuery,原生javascript制作的tab切换效果源码。点击上面的标题即可实现对应页面的切换功能,非常具有实用价值。 为大家分享的js实现的tab标签切换效果代码如下 <!...
2017-03-31
回到顶部