zoukankan      html  css  js  c++  java
  • 前端 new和instanceof JavaScript

    new和instanceof的内部机制

    new

    代码例子

    var Func=function(){
    };
    var func=new Func ();

    new共经过4个阶段

    1.创建一个空对象

    var obj = new Object();

    2.设置原型链

    obj.__proto__=Func.prototype;

    3.让Func中的this指向obj,并执行Func的函数体。

    var result = Func.call(obj);

    4.判断Func的返回值类型,如果是基本值类型,返回obj;如果是引用类型,就返回这个引用类型的对象。

    if (typeof(result) == "object"){
      func=result;
    }
    else{
        func=obj;;
    }

    instanceof

    instanceof运算符用于判断一个对象的原型链是否存在一个构造函数的prototype属性。

    语法:object instanceof constructor

    参数:object(要检测的对象)  constructor(某个构造函数)

    描述:instanceof运算符用来检测constructor.prototype是否存在于参数object的原型链上

     下面通过代码阐述instanceof的内部机制,假设有x instanceof y 一条语句,,则其内部实际做了如下判断:

    while(x.__proto__!==null) {
        if(x.__proto__===y.prototype) {
            return true;
            break;
        }
        x.__proto__ = x.__proto__.proto__;
    }
    if(x.__proto__==null) {return false;}

    x会一直沿着隐式原型链__proto__向上查找直到x.__proto__.__proto__.......===y.prototype为止,如果找到则返回true,即x为y的实例,否则返回false,x不是y的实例。

    相关面试题

    function F() {}
    function O() {}
    
    O.prototype = new F();
    var obj = new O();
    
    console.log(obj instanceof O); // true
    console.log(obj instanceof F); // true
    console.log(obj.__proto__ === O.prototype); // true
    console.log(obj.__proto__.__proto__ === F.prototype); // true

    根据new的内部机制改写代码

    function F() {}
    function O() {}
    
    var obj = (function () {
        var obj1 = {};
        obj1.__proto__ = F.prototype; // new F();
        O.prototype = obj1; // O.prototype = new F();
        obj.__proto__ = O.prototype; // new O();
        obj.__proto__ = obj1;
        return obj;
    })()

    如果改一下代码顺序,结果将不同

    function F() {}
    function O() {}
    
    var obj = new O();
    O.prototype = new F();
    
    
    console.log(obj instanceof O); // false
    console.log(obj instanceof F); // false
    console.log(obj.__proto__ === O.prototype); // false
    console.log(obj.__proto__.__proto__ === F.prototype); // false

    顺便扩展一下原型和原型链

    构造函数:function Foo() {};

    实例对象:let f1=new Foo;

    let o1=new Foo();

    概念:

    1、构造函数:用来初始化新创建的对象的函数是构造函数。在例子中,Foo()函数是构造函数。

    2、实例对象:通过构造函数的new操作创建的对象是实例对象。可以用一个构造函数,构造多个实例对象

    每个函数都有 prototype 属性,除了 Function.prototype.bind(),该属性指向原型。

    每个对象都有 __proto__ 属性,指向了创建该对象的构造函数的原型。其实这个属性指向了 [[prototype]],但是 [[prototype]] 是内部属性,我们并不能访问到,所以使用 _proto_ 来访问。

  • 相关阅读:
    通过加载Xib文件来创建UITableViewCell造成复用数据混乱问题方案
    iOS开发过程中常见错误问题及解决方案
    iOS开发常用第三方库
    KVC和KVO的理解(底层实现原理)
    iOS面试必备-iOS基础知识
    iOS应用适配IPV6
    Runtime运行时的那点事儿
    iOS应用性能调优的25个建议和技巧
    iOS清除缓存功能开发
    微信浏览器跳转页面后再返回,如何恢复到跳转前的位置的问题。
  • 原文地址:https://www.cnblogs.com/lhh520/p/10229678.html
Copyright © 2011-2022 走看看