首页 > 其他分享 >new方法返回的是构造函数的prototype也就是一个对象

new方法返回的是构造函数的prototype也就是一个对象

时间:2023-11-11 15:55:18浏览次数:23  
标签:console log proto 对象 new prototype 构造函数

请问以下JS代码的输出是什么?

let A = function() {}

A.prototype.a = 1;

let B = new A();

A.prototype = {
  b: 2,
  c: 3
}

let C = new A();

A.prototype.d = 4;

console.log(B.a);
console.log(B.b);
console.log(C.c);
console.log(C.d);

1、undefined、3、4

首先需要明确new方法返回的是构造函数的prototype也就是一个对象,其中直接给对象上不存在的a变量赋值相当于往这个对象添加了一个a变量,因此B可以访问到变量a,
但是后续是直接赋值了一个对象,那么原对象就无法感知到了,所以B访问不到新对象的变量b,也因此产生了新旧两个prototype的引用。
C的话拿到的是新对象以及往新对象里面新增的d变量。

let A = function() {}
A.prototype.a = 1; 
//此时 A.prototype = { a: 1 }


let B = new A(); //此时 B = {}
//在创建B时,已将B._proto_ = A.prototype = { a: 1 }
//即使后面A.prototype重新赋值,将A.prototype开辟了新的空间指向别的对象
//B._proto_并没有改,还是指向{a:1}这个对象


A.prototype = { //此时 A.prototype = { b: 2, c: 3 }
  b: 2,
  c: 3
}
let C = new A(); //C = {}
A.prototype.d = 4;//此时A.prototype = { b: 2, c: 3, d: 4 }

console.log(B.a); //1
console.log(B.b); //undefined
console.log(C.c); //3
console.log(C.d); //4

//C.d
//着重区分: A.prototype.d = 4 和 A.prototype 重新赋值 不是一个概念 
//A.prototype重新赋值时,A.prototype已经指向另一个对象了   
//A.prototype.d = 4时,访问的还是同一个A.prototype 对象 

如果 let B = new A(); 之后
加一个 A.prototype.b = 999;
那么 console.log(B.b); B.b就是999

在创建B时,已将B.proto = A.prototype; 后面A.prototype重新赋值,只是将A.prototype开辟了新的空间,B._proto_并没有改,还是{a:1};

1.A是个构造函数,B是构造函数的实例对象 => B.proto === A.prototype, A.prototype.a = 1 => B.a === 1

2.A.prototype = { b : 2 , c : 3 } , A的原型对象重新赋值,但是不会影响之前已经new 出来的B实例, B实例的原型(B.proto)跟这个A函数的原型对象没任何关系,但是这个A函数新的原型对象是后续A实例对象的原型(x.proto),即后续的实例可以访问该新原型对象中的属性 => B.b === undefined // C.c === 3

此题需要明确2点
1.new 构造函数内部发生了什么
new A 首先this= new Object obj.__proto__指向A.prototype 执行函数内部代码绑定this相关属性
如果 显示return 对象返回对象
如果显示return undefine 都默认返回this

2.堆内存地址指向 可以看到创建B时 上述new后原型指向一个含有a为1的对象
而后A.prototype指向另一块地址,
也就是b.__proto__指向与A.prototype指向脱钩的ap变化指向只表明ap不指向那个有a=1的内存区域 所以b原型上只有a

标签:console,log,proto,对象,new,prototype,构造函数
From: https://www.cnblogs.com/longmo666/p/17825988.html

相关文章

  • js常见的继承方式包括原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继
    js常见的继承方式包括原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承,以及ES6新增的class继承,但不包括关联继承https://www.cnblogs.com/Leophen/p/11401734.html构造函数继承是每次继承都会把父类的所有属性方法全部拷贝一份,而对于公用的方法......
  • new是以Date为构造函数产生对象的,Date()是直接调用了构造函数。控制台在输出日期对象
    Date()//输出:(字符串)'WedSep21202216:53:16GMT+0800(中国标准时间)'newDate()//输出:WedSep21202216:53:23GMT+0800(中国标准时间)new是以Date为构造函数产生对象的,Date()是直接调用了构造函数。控制台在输出日期对象时调用了tostring......
  • C++中虚继承时的构造函数
    在虚继承中,虚基类是由最终的派生类初始化的,换句话说,最终派生类的构造函数必须要调用虚基类的构造函数。对最终的派生类来说,虚基类是间接基类,而不是直接基类。这跟普通继承不同,在普通继承中,派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。下面我们以菱形继承为例来......
  • "+new Array(017)" 这段代码输出为 NaN
    首先,前面+是一元运算符,相当于我们说的正负,无运算效果,但是可以将字符串等转为number类型。此题中017其实是八进制,故而是是Array(15)。这里相当于对于一个未赋值但是长度为15的数组进行number类型转化,其结果为NaN八进制的17转为二进制:001111,再转为十进制的15(8+4+2+1)+运算符......
  • What's new in Pika v3.5.0
    时隔两年,Pika社区正式发布经由社区50多人参与开发并在360生产环境验证可用的v3.5.0版本,新版本在提升性能的同时,也支持了Codis集群部署,BlobDBKV分离,增加Exporter等新特性。我们将详细介绍该版本引入的重要新特性。1去除Rsync在v3.5.0版本之前,Pika使用Rsync工具......
  • 开发时推荐使用Map map = new HashMap()
    Mapmap=newHashMap();Map是一个接口,HashMap是具体的实现类。由于接口就是多个类的共有规范(里面的抽象方法),是一种引用数据类型,一个抽象的概念,不能被实例化,因此接口需要由具体的类来实现。这条代码指明:由HashMap类来实现接口Map中描述的方法。HashMapmap=newHashMap(......
  • PowerShell 函数遇见 Newtonsoft.Json.JsonReaderException: The reader's MaxDepth o
    问题描述创建PowerShellAzureDurableFunction,执行大量的PowerShell脚本操作AzureResource,遇见了一个非常非常奇怪的问题:Function'Hello1(Activity)'failedwithanerror.Reason:Newtonsoft.Json.JsonReaderException:Thereader'sMaxDepthof64hasbeenexceeded.Pa......
  • 【Azure Durable Function】PowerShell Activity 函数遇见 Newtonsoft.Json.JsonReade
    问题描述创建PowerShellAzureDurableFunction,执行大量的PowerShell脚本操作AzureResource,遇见了一个非常非常奇怪的问题:Function'Hello1(Activity)'failedwithanerror.Reason:Newtonsoft.Json.JsonReaderException:Thereader'sMaxDepthof64hasbeenexceeded.......
  • new代码
    #include<WinSock2.h>#include<ws2tcpip.h>#include<stdio.h>#include<windows.h>#pragmacomment(lib,"Ws2_32.lib")structhostent*FARgethostbyname( constchar*name);intWSAStartup(WORDwVersionRequeste......
  • Java中用引号创建String对象和用构造函数的区别
    创建一个String对象一般有以下两种方式:Stringstr1="abcd";Stringstr2=newString("abcd");这两种方式有什么区别呢?我们可以通过下面两个小例子来说明.Example1:Stringa="abcd";Stringb="abcd";System.out.println(a==b);//True......