javaScript神奇的new操作符

2018-06-24 00:07:42来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

在使用new操作符实例化构造函数的时候,你有没有产生过困惑究竟new操作符帮我们做了什么?接下来我们就来揭开它的神秘面纱,来看一下其内部究竟是怎么运行的。

我们先看一个例子:
function Person(name,age){
    this.name=name;
    this.age=age;
}
Person.prototype.getPerson=function(){
  console.log(this.name+'的年龄是'+this.age);
};

 

new实例化,调用getPerson方法,我们得到了‘张三的年龄是13’的结果

var zhangSan=new Person('张三','13');
zhangSan.getPerson();   //张三的年龄是13

那么这整个过程究竟是怎样的呢?接下来我们就来详细分析一下,首先 new Person('张三','13') 实例化的过程:
function new2(func){
    //创建一个对象
    var newObject={};
    //设置原型链
    newObject._proto_=func.prototype;
    //修改this指向新对象newObject,并执行函数体func
    var result=func.apply(newObject,arguments);
    //判断函数体的返回类型,如果是引用类型,返回这个引用类型
    if(result instanceof Object){
        return result;
    //否则,返回新对象newObject
    }else{
        return newObject;
    }
}

这个过程只是模拟理解,实际上实例对象有一个内部属性[[Prototype]]指向构造函数的原型对象,而脚本中并没有标准的方式访问[[Prototype]],但 Firefox、Safari 和 Chrome 在每个对象上都支持一个属性__proto__;
而在其他实现中,这个属性对脚本则是完全不可见的



有的同学可能会困惑new操作符实例化返回的结果不都是一个新的对象吗?我们来试验一下:
function Person(name,age){
    this.name=name;
    this.age=age;
    return {
        'aaa':'哈哈哈,我是不是很奇怪'
    }
}
Person.prototype.getPerson=function(){
    console.log(this.name+'的年龄是'+this.age);
};

console.log(new Person('张三','13')); //{'aaa':'哈哈哈,我是不是很奇怪'}

上面的结果返回了对象{'aaa':'哈哈哈,我是不是很奇怪'},所以一般情况下构造函数不返回任何值。

了解了new操作符内部的工作原理,我们就来看一下zhangSan.getPerson()调用方法的这个过程,细心的同学可以留意到getPerson这个方法我们绑在了构造函数的原型上,而实例化的对象本身并没有这个方法,那么它是怎样调用并得到了我们想要的结果呢?

答案就是我们刚刚分析的new操作符的工作原理,实例化的对象有一个内部属性[[Prototype]],指向构造函数的原型对象,当我们调用某一个方法时:
1.都会先执行第一次搜索:实例化对象本身有无此方法,如果有,则返回实例化对象本身定义的方法调用;
2.如果无,则执行第二次搜索,内部属性[[Prototype]]指向的构造函数的原型对象,如果能找到,则返回原型中的定义的方法调用,如果没有,则会报错。


在本示例中,则是返回了原型中定义的方法调用,得到了‘张三的年龄是13’的结果。

这个过程的模拟代码如下:
function getProperty(obj, prop) {
  if (obj.hasOwnProperty(prop))
    return obj[prop]
 
  else if (obj.__proto__ !== null)
    return getProperty(obj.__proto__, prop)
 
  else
    return undefined
}

 

 

参考资料:

1.Javascript – How Prototypal Inheritance really works

2.new运算符


			   
			   

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:javascript 利用FileReader和滤镜上传图片预览

下一篇:【前端】前端笔试题 [1]