- 以下的所有原文收录在仓库: github.com/yayxs/top-f…
- 首次发布时间:2020年04月24日
- 更新时间:2020年11月25号
- 建议阅读地址: ……written/new.html
- 建议阅读时长:15min
- 建议阅读对象:初中级前端工程师、Js爱好者
延伸的面试题
根据new操作符
相关的知识点一般会 延伸出以下的面试题 ,面试官你是否有很多问号
- 问题一:new 之后都做了些什么??
- 问题二:能否手写 new 操作符原理??
- 问题三:通过 new 的方式创建对象和通过字面量创建有什么区别
- 创建一个空的简单 JavaScript 对象(即
{}
);- 链接该对象(即设置该对象的构造函数)到另一个对象 ;
- 将步骤 1 新创建的对象作为
this
的上下文 ;- 如果该函数没有返回对象,则返回
this
。
以上 4 条是MDN
上关于 new 操作符(或者说关键字)的面试,简单的来体验下利用构造函数来new
一个对象
function Person(name, age) {
console.log("this", this);
this.name = name;
this.age = age;
}
// 然后在**构造函数添加原型方法**
Person.prototype.height = 180;
Person.prototype.sayName = function() {
console.log(this.name);
};
let p = new Person("yayxs", 20);
console.log(p.name); // yayxs
console.log(p.age);
20;
p.sayName(); // yayxs
console.log(p.__proto__ === Person.prototype); // 对象p(实例)的原型属性指向构造函数的原型,
既然我们通过自定义,其使用的方式大体跟new
是一样的。
// ------ 使用new的时候
const p = myNew Person('yayxs',20) // 其返回的结果是一个对象
// ---------
第一版的 myNew
大体思路是声明一个对象,取出当前的构造函数,以及参数,让新对象的原型属性指向构造函数的原型,然后调用构造函数,传入对象的参数
function myNew() {
let obj = new Object(),
[constructor, ...args] = [...arguments];
obj.__proto__ = constructor.prototype;
constructor.apply(obj, args);
return obj;
}
第二版的myNew
经过上文的简单案例我们可以得知,
-
new
一个构造函数得到一个对象,它的原型属性(也就是** proto **)与该构造函数的原型是全等 -
new
通过构造函数Persion
创建出来的实例可以访问到构造函数中的属性,就像这样console.log(xiaoMing.name); // 小明
-
言简意赅:new 出来的实例对象通过原型链和构造函数联系起来
构造函数说白了也是一个函数,那是函数就可以有返回值
function Person(name) {
this.name = name;
// return 1; // 返回内部新创建的对象
// return "1"; // 返回内部新创建的对象
// return null; // 返回内部新创建的对象
// return undefined; // 返回内部新创建的对象
// return {}; // {} // 直接返回
return function() {}; // 直接返回
return [1]; // [1] // 直接返回
}
let p = new Person("李四");
console.log(p);
有了给构造函数返回一个值得想法,那就通过不同的数据类型
进行测试得出结论
- 不同的数据类型返回的效果是不一样的,像数字 1 字符串”1“ ,返回的依然是内部创建的对象
- 那如果返回一个对象({})或者说数组([]) 都会直接返回回去
小结
也就是说,构造函数一般不需要return
- 返回一般的数据类型吧,不起作用
- 返回对象吧, new 的意义又何在呢
function myNew(){
let obj = new Object(),
[constructor,...args] = [...arguments]
obj.__proto__ = constructor.prototype;
let res = constructor.apply(obj,args)
return = typeof res === 'object' ? res : obj;
}
手写一个自己的 myNew 小结
如果自己实现一个 new 的话,首先要满足它的几点效果
-
一个构造函数会返回一个对象,那函数里就应该有对象
let obj = {};
-
并将其
__proto__
属性指向构造函数的prototype
属性obj.__proto__ = constructor.prototype;
-
调用构造函数,绑定 this
constructor.apply(obj, args);
-
返回原始值需要忽略,返回对象需要正常处理
res instanceof Object ? res : obj;
箭头函数使用new
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor
- 不可以当作构造函数,也就是说,不可以使用
new
命令,否则会抛出一个错误
this
指向的固定化,并不是因为箭头函数内部有绑定this
的机制,实际原因是箭头函数根本没有自己的this
,导致内部的this
就是外层代码块的this
。正是因为它没有this
,所以也就不能用作构造函数。