• 前端 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_ 来访问。

  • 相关阅读:
    fun()可拆分赋值 fun()可以拆, 变成 fun 和 括号, fun 可以赋值
    全局变量是列表list 的改变, 竟然在局部,用append 就可以了..... 不用global sth...
    * args 和 **kwargs
    三元运算符 c = a if a>b else b
    终于明白为什么要赋值给ret ,
    只要下面看到func() 带括号的,就会弹上去找对应的函数,然后执行相应的函数块
    关于mysql复合主键
    再次回顾post请求中的enctype
    关于crontab以及输出重定向
    HTTP请求中的form data和request payload的区别
  • 原文地址:https://www.cnblogs.com/lhh520/p/10229678.html
Copyright © 2020-2023  润新知