Code Monkey home page Code Monkey logo

Comments (52)

zwmmm avatar zwmmm commented on May 13, 2024 992

这样写是不是简单点啊

function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);
    const ret = fn.apply(obj, arg);
    return ret instanceof Object ? ret : obj;
}

from daily-interview-question.

Hiker9527 avatar Hiker9527 commented on May 13, 2024 54

先理清楚 new 关键字调用函数都的具体过程,那么写出来就很清楚了

  1. 首先创建一个空的对象,空对象的__proto__属性指向构造函数的原型对象
  2. 把上面创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象
  3. 如果构造函数返回一个非基本类型的值,则返回这个值,否则上面创建的对象
function _new(fn, ...arg) {
    var obj = Object.create(fn.prototype);
    const result = fn.apply(obj, ...arg);
    return Object.prototype.toString.call(result) == '[object Object]' ? result : obj;
}

from daily-interview-question.

atheist1 avatar atheist1 commented on May 13, 2024 39

@zwmmm 你是对的,我写的有点问题

from daily-interview-question.

hwxy avatar hwxy commented on May 13, 2024 24

function _new(fn, ...arg) {
var obj = Object.create(fn.prototype);
fn.call(obj, ...arg);
let result = fn();
return Object.prototype.toString.call(result) == '[object Object]' ? result : obj;
}

from daily-interview-question.

nnecec avatar nnecec commented on May 13, 2024 19
function _new(){
  const obj = {}
  const Constructor = Array.prototype.shift.call(arguments)

  obj.__proto__ = Constructor.prototype
  const result = Constructor.apply(obj, arguments)

  return typeof result === 'object' ? result : obj
}

from daily-interview-question.

chenjigeng avatar chenjigeng commented on May 13, 2024 18
/**
 *
 *
 * @param {Function} fn
 */
function _new(fn, ...args) {
	const obj = {};
	Object.setPrototypeOf(obj, fn.prototype);
	const result = fn.apply(obj, args);
	// 根据规范,返回 null 和 undefined 不处理,依然返回obj
	return result instanceof Object ? result : obj;
}

from daily-interview-question.

harryliuy avatar harryliuy commented on May 13, 2024 13

这样写是不是简单点啊

function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);
    const ret = fn.apply(obj, arg);
    return ret instanceof Object ? ret : obj;
}

关于为什么最后要判断 return ret instanceof Object ? ret : obj
instanceof Object 来判断是否是对象,包含Array,Object,Function、RegExp、Date
构造函数是可以自己指定返回一个对象的

function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);
    const ret = fn.apply(obj, arg);
    //return ret instanceof Object ? ret : obj;
    return obj;
  }

  function A(d) {
    this.d = d;
    return {
      a: 6
    };
  }
  console.log(new A(123));  //{a: 6}
  console.log(_new(A, 123)); //A {d: 123}

from daily-interview-question.

mongonice avatar mongonice commented on May 13, 2024 7

new运算符都做了哪些操作呢?
1、创建了一个新对象(是Object类型的数据)
2、将this指向新对象
3、将创建的对象的原型指向构造函数的原型
4、返回一个对象(如果构造函数本身有返回值且是对象类型,就返回本身的返回值,如果没有才返回新对象)

下面就写一个实现new功能的函数:

function mynew () {
     // 1、创建一个新对象
     const obj = Object.create({});    // 也可以写成 const obj = {}
     // 2、将this指向该对象
     let Fn = [].shift.call(arguments);    // 把构造函数分离出来
     let returnObj = Fn.apply(obj, arguments);     // 通过apply将this指向由Fn变为obj
     
     // 3、将新对象的原型指向构造函数的原型
     obj.__proto__ = Fn.prototype
     
    // 4、返回对象(如果构造函数有返回对象,那么就返回构造函数的对象,如果没有就返回新对象)
    return Object.prototype.toString.call(returnObj) == '[object Object]' ? returnObj : obj;
}

from daily-interview-question.

Mini-Web avatar Mini-Web commented on May 13, 2024 5
function miniNew(...args) {
    const [constructor, ...otherArgs] = args;
    
    if(typeof constructor !== 'function') {
        throw new TypeError('constructor is not a function');
    };

    // 1~2 步骤简单写法 const obj = Object.create(constructor.prototype);   

    // 1.创建一个空的简单JavaScript对象(即{});
    const obj = {};   

    // 2.链接该对象(即设置该对象的构造函数)到另一个对象 ;
    Object.setPrototypeOf(obj, constructor.prototype)

    // 3.将步骤1新创建的对象作为this的上下文
    const result = constructor.apply(obj, otherArgs);

    // 4.如果该函数没有返回对象,则返回this。
    return isPrimitive(result) ? obj : result
}

function isPrimitive(value) {
    return value == null || ['string', 'number', 'boolean', 'symbol'].includes(typeof(value))
}

function A(x, y) {
    this.x = x;
    this.y = y;
}

var a = miniNew(A, 1,2)

from daily-interview-question.

nano-papa avatar nano-papa commented on May 13, 2024 3

proto

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

from daily-interview-question.

zwmmm avatar zwmmm commented on May 13, 2024 2

这样写是不是简单点啊

function  _new(fn,... arg){
     const  obj  =  Object。创造(fn。原型);
    const  ret  =  fn。申请(obj,arg);
    返回 ret instanceof  对象 ?ret  obj;
}

这样ret不是一直都是undefined吗?res instanceof Object就一直是false啊

构造函数是默认返回对象的(但是这个是没有返回值的)。但是你也可以自己return一个对象。

from daily-interview-question.

arixse avatar arixse commented on May 13, 2024 2
function __new__(_Contructor,...args) {
	let obj = new Object();
	obj.__proto__ = _Contructor.prototype;
	_Contructor.apply(obj,args);
	return obj;
}

image

from daily-interview-question.

zhoushaw avatar zhoushaw commented on May 13, 2024 2

判断ret的作用是?

function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);
    const ret = fn.apply(obj, arg);
    return ret instanceof Object ? ret : obj;
}

WX20190819-182759@2x

详细可参考mdn关于new运算符第四条定义

from daily-interview-question.

yayxs avatar yayxs commented on May 13, 2024 2

JavaScript中的new操作符

面试题

根据new操作符相关的知识点一般会 延伸出以下的面试题 ,面试官你是否有很多问号

  • 问题一:new 之后都做了些什么??
  • 问题二:能否手写new操作符原理??

mdn关于new运算符关键字的描述

  1. 创建一个空的简单JavaScript对象(即{});
  2. 链接该对象(即设置该对象的构造函数)到另一个对象 ;
  3. 将步骤1新创建的对象作为this的上下文 ;
  4. 如果该函数没有返回对象,则返回this

以上4条是MDN 上关于new 操作符(或者说关键字)的面试,简单的来体验下利用构造函数来new 一个对象

var self;

function Person(name) {
  console.log(this);
  self = this;
  this.name = name;
}
let p = new Person("张三");
console.log(p);
console.log(self === p); // true 构造函数中的this 绑定在了p这个对象上
console.log(p.__proto__ === Person.prototype); // 对象p的原型属性指向构造函数的原型,这样也就保证了实例能够访问在构造函数原型中定义的属性和方法。

然后在构造函数添加原型方法

function Persion(name){
    this.name = name
}
console.log(Persion.prototype)
Persion.prototype.sayHello = function(){
    console.log(this) // 指向构造出的对象
    console.log(this.name) // 小明
}

let xiaoMing = new Persion('小明')
xiaoMing.sayHello()

经过上文的简单案例我们可以得知,

  • 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 的意义又何在呢

手写一个自己的myNew

如果自己实现一个new 的话,首先要满足它的几点效果

  1. 一个构造函数会返回一个对象,那函数里就应该有对象

    let obj ={}
  2. 并将其__proto__属性指向构造函数的prototype属性

    obj.__proto__ = constructor.prototype;
  3. 调用构造函数,绑定this

    constructor.apply(obj, args)
  4. 返回原始值需要忽略,返回对象需要正常处理

    res instanceof Object ? res : obj

测试成果

function myNew() {
  let [constructor, ...args] = [...arguments];
  let obj = {};
  obj.__proto__ = constructor.prototype;

  let res = constructor.apply(obj, args);
  return res instanceof Object ? res : obj;
}

function Person(name) {
  this.name = name;
//   return {};
}

Person.prototype.sayHi = function () {
  console.log(`原型方法中的函数--${this.name}`);
};
let p1 = myNew(Person, "测试");
// console.log(p1)
p1.sayHi();
console.log(p1.name);

from daily-interview-question.

ruochuan12 avatar ruochuan12 commented on May 13, 2024 1

之前写过一篇模拟实现new的文章~
面试官问:能否模拟实现JSnew操作符

我的这篇文章主要提出了对返回值是函数和对象的处理,还有对new.target的简单处理。

// 去除了注释
function newOperator(ctor){
    if(typeof ctor !== 'function'){
      throw 'newOperator function the first param must be a function';
    }
    newOperator.target = ctor;
    var newObj = Object.create(ctor.prototype);
    var argsArr = [].slice.call(arguments, 1);
    var ctorReturnResult = ctor.apply(newObj, argsArr);
    var isObject = typeof ctorReturnResult === 'object' && ctorReturnResult !== null;
    var isFunction = typeof ctorReturnResult === 'function';
    if(isObject || isFunction){
        return ctorReturnResult;
    }
    return newObj;
}

from daily-interview-question.

calmchang avatar calmchang commented on May 13, 2024 1

改进一下

function create(fn,...args){
  if(fn===null)return null;
  let obj =  Object.create(fn.prototype);
  let ret= fn.apply(obj,args);
  if( ['string','number','boolean'].includes( typeof ret ) ){
    ret=new fn(args);
    return ret;
  }
  return typeof ret==='object'?ret:obj;
}

create(Number,123)
create(String,'abc')
以上情况也支持了

from daily-interview-question.

JTangming avatar JTangming commented on May 13, 2024 1

实例代码:

function Person(name){ 
  this.name = name;
} 
Person.prototype.getName = function() {
    return this.name;
}

var p1 = new Person('Dan');

console.log(p1); // Person {name: "Dan"}
console.log(p1.__proto__ === Person.prototype); // true

new 操作符实现了如下的功能:

  • 创建一个新对象
  • 新对象继承了构造函数的原型
  • 构造函数的 this 指向新对象,并执行构造函数
  • 最后隐式的返回 this,即新对象

前面提到了隐式的返回,如果是显式返回呢?

构造函数如果返回基本类型,则还是会返回原来的 this (新对象)。如果返回的是引用类型,则返回该返回值。(可以自己在上面例子加上代码验证一下)

new 操作符的模拟实现

function createNew(func, ...args) {
    let obj = {};
    // 将空对象指向构造函数的原型链
    Object.setPrototypeOf(obj, func.prototype);
    // obj 绑定到构造函数上,便可以访问构造函数中的属性
    let result = func.apply(obj, args);
    // 如果返回的 result 是一个对象则返回该对象,new 方法失效,否则返回 obj
    return result instanceof Object ? result : obj;
}

Object.setPrototypeOf()是ECMAScript 6最新草案中的方法,相对于 Object.prototype.proto ,它被认为是修改对象原型更合适的方法

写个测试用例:

function Test(name, age) {
    this.name = name;
    this.age = age;
}

let test = createNew(Test, 'Dan', 20);
console.log(test.name); // Dan
console.log(test.age); // 20

Reference

from daily-interview-question.

GuoYuFu123 avatar GuoYuFu123 commented on May 13, 2024

我也贴一个
function Dog(name) {
this.name = name
this.say = function () {
console.log('name = ' + this.name)
}
}
function Cat(name) {
this.name = name
this.say = function () {
console.log('name = ' + this.name)
}
}
function _new(fn, ...arg) {
const obj = {};
obj.proto = fn.prototype;
fn.apply(obj, arg)
return Object.prototype.toString.call(obj) == '[object Object]'? obj : {}
}
var dog = _new(Dog,'xxx')
dog.say() //'name = xxx'
console.log(dog instanceof Dog) //true
var cat = _new(Cat, 'carname');
cat.say() //'name = carname'
console.log(cat instanceof Cat) //true

from daily-interview-question.

flysme avatar flysme commented on May 13, 2024

写的真好

from daily-interview-question.

lkoma avatar lkoma commented on May 13, 2024

这样写是不是简单点啊

function  _new(fn,... arg){
     const  obj  =  Object。创造(fn。原型);
    const  ret  =  fn。申请(obj,arg);
    返回 ret instanceof  对象 ?ret  obj;
}

这样ret不是一直都是undefined吗?res instanceof Object就一直是false啊

from daily-interview-question.

atheist1 avatar atheist1 commented on May 13, 2024

这样写是不是简单点啊

function  _new(fn,... arg){
     const  obj  =  Object。创造(fn。原型);
    const  ret  =  fn。申请(obj,arg);
    返回 ret instanceof  对象 ?ret  obj;
}

这样ret不是一直都是undefined吗?res instanceof Object就一直是false啊

当然不是,这里判断构造函数执行的返回类型,如果构造函数执行结果返回的是个对象不就是true了

from daily-interview-question.

cliYao avatar cliYao commented on May 13, 2024

function _new(fn , ...args){
const obj={}
const Constructor = fn
obj.proto = Constructor.prototype
const result = Constructor.call(obj , ...args)
return typeof result === "object" ? result : obj
}

from daily-interview-question.

ZTH520 avatar ZTH520 commented on May 13, 2024

function _new(fn, ...args){
let obj = {}
Object.setPrototypeOf(obj,fn.prototype)
let result = fn.apply(obj,args)
return result instanceof Object ? result : obj
}

from daily-interview-question.

harryliuy avatar harryliuy commented on May 13, 2024

先理清楚 new 关键字调用函数都的具体过程,那么写出来就很清楚了

  1. 首先创建一个空的对象,空对象的__proto__属性指向构造函数的原型对象
  2. 把上面创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象
  3. 如果构造函数返回一个非基本类型的值,则返回这个值,否则上面创建的对象
function _new(fn, ...arg) {
    var obj = Object.create(fn.prototype);
    const result = fn.apply(obj, ...arg);
    return Object.prototype.toString.call(result) == '[object Object]' ? result : obj;
}

两处错误

from daily-interview-question.

f4762690 avatar f4762690 commented on May 13, 2024

鉴于十三题可以说的东西很多,就先看了十四题,作为一个单身狗,new的对象都是一个小狗啊

// 实现一个new
var Dog = function(name) {
  this.name = name
}
Dog.prototype.bark = function() {
  console.log('wangwang')
}
Dog.prototype.sayName = function() {
  console.log('my name is ' + this.name)
}
let sanmao = new Dog('三毛')
sanmao.sayName()
sanmao.bark()
// new 的作用
// 创建一个新对象obj
// 把obj的__proto__指向Dog.prototype 实现继承
// 执行构造函数,传递参数,改变this指向 Dog.call(obj, ...args)
// 最后把obj赋值给sanmao
var _new = function() {
  let constructor = Array.prototype.shift.call(arguments)
  let args = arguments
  const obj = new Object()
  obj.__proto__ = constructor.prototype
  constructor.call(obj, ...args)
  return obj
}
var simao = _new(Dog, 'simao')
simao.bark()
simao.sayName()
console.log(simao instanceof Dog) // true

内部创建对象的时候也不能使用new来吧..

from daily-interview-question.

wang-hongliang avatar wang-hongliang commented on May 13, 2024

// 首先创建一个空的对象,空对象的__proto__属性指向构造函数的原型对象
// 把上面创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象
// 如果构造函数返回一个非基本类型的值,则返回这个值,否则上面创建的对象

from daily-interview-question.

ravencrown avatar ravencrown commented on May 13, 2024
function New (func) {
    var res = {}
    if (func.prototype !== null) {
        res.__protp__ = func.prototype
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1))
    if ((typeof ret === 'object' || typeof ret === 'function') && ret !== null) {
        return ret
    }
    return res
}

from daily-interview-question.

Nina0408 avatar Nina0408 commented on May 13, 2024

function create(){
var obj = new Object();
var src = Array.prototype.shift.call(arguments);
if (src == null) {
return obj;
}
obj._proto = src.prototype;
obj.call(src, ...arguments);
return obj;
}

from daily-interview-question.

iendeavor avatar iendeavor commented on May 13, 2024

應另外確認null,new關鍵字針對null是處理成回傳this

function _new(fn, ...args) {
  const object = Object.create(fn.prototype)
  const result = fn.call(object, ...args)
  return typeof result === 'object' && result !== null ? result : object
}

from daily-interview-question.

caixianglin avatar caixianglin commented on May 13, 2024

function _new(fn, ...arg) {
var obj = Object.create(fn.prototype);
fn.call(obj, ...arg);
let result = fn();
return Object.prototype.toString.call(result) == '[object Object]' ? result : obj;
}

call和apply在绑定this时会立即执行,bind才是单纯绑定this,所以你得

fn.call(obj, ...arg); // 已经是执行了
let result = fn();
上面换成bind,或直接let result = fn.call

from daily-interview-question.

wython avatar wython commented on May 13, 2024

建议去mdn看下__proto__,这个属性性能极差,而且已经废弃(不安全)。应该在构造函数的原型上做手脚,而不是利用实例的__proto__做手脚。实例和构造函数还是要区分的。

from daily-interview-question.

NuoHui avatar NuoHui commented on May 13, 2024
function _new(fx, ...args) {
  // 创建一个新对象
  // 对象的__proto__指向构建函数的prototype
  const target = Object.create(fx.prototype);
  // 执行代码时候, 绑定this指向新的对象
  const execResult = fx.apply(target, args);
  // 如果构造函数有返回值, 返回构造函数的值, 否则返回新对象
  return Object.prototype.toString.call(execResult) === '[object Object]' ? execResult : target;
};

from daily-interview-question.

Jouryjc avatar Jouryjc commented on May 13, 2024

constructor.call(obj, ...args)

这里需要返回值,判断是不是对象,是的话返回该对象,不是的话返回obj

from daily-interview-question.

Y-qwq avatar Y-qwq commented on May 13, 2024

先理清楚 new 关键字调用函数都的具体过程,那么写出来就很清楚了

  1. 首先创建一个空的对象,空对象的__proto__属性指向构造函数的原型对象
  2. 把上面创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象
  3. 如果构造函数返回一个非基本类型的值,则返回这个值,否则上面创建的对象
function _new(fn, ...arg) {
    var obj = Object.create(fn.prototype);
    const result = fn.apply(obj, ...arg);
    return Object.prototype.toString.call(result) == '[object Object]' ? result : obj;
}

const result = fn.apply(obj, ...arg);的apply应该改为call吧,或者把...去掉

from daily-interview-question.

houmao avatar houmao commented on May 13, 2024
class Foo {
  constructor() {
    this.foo = 42;
  }
}

function _new(fn, ...arg) {
  const obj = Object.create(fn.prototype);
  const ret = fn.apply(obj, arg);
  return ret instanceof Object ? ret : obj;
}

new Foo(); //{foo: 42}
_new(Foo); //TypeError: Class constructor Foo cannot be invoked without 'new'

这个_new并不等价new

from daily-interview-question.

weixiaoxu123 avatar weixiaoxu123 commented on May 13, 2024

var obj = new A()
new 操作:
var obj = {} obj.__proto__ = A.prototype A.call(obj,arguments)

from daily-interview-question.

liuxingit avatar liuxingit commented on May 13, 2024

判断ret的作用是?

function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);
    const ret = fn.apply(obj, arg);
    return ret instanceof Object ? ret : obj;
}

from daily-interview-question.

aeolusheath avatar aeolusheath commented on May 13, 2024

new 关键点

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。new 关键字会进行如下的操作:

  • 创建一个空的简单JavaScript对象(即{});

  • 链接该对象(即设置该对象的构造函数)到另一个对象 ;

  • 将步骤1新创建的对象作为this的上下文 ;

  • 如果该函数没有返回对象,则返回this。 【很关键】


function Dog(name) {
  this.name = name
}

Dog.prototype.sayHi = function() {
  console.log('hello its me')
}

Dog.prototype.sayName = function() {
  console.log('my name is ' + this.name)
}

方法一

// 实现一个new
// 1,创建一个新的对象obj
// 2,将obj的__proto__指向Dog.prototype实现继承
// 3,执行构造函数,传递参数,改变this指向

// 方法一
function _new() {
  let args = arguments
  let constructor = Array.prototype.shift.call(args)
  const obj = new Object()
  Object.setPrototypeOf(obj, constructor.prototype)// 和下面一句是同样的效果
  // obj.__proto__ = constructor.prototype
  constructor.call(obj, ...args)
  return obj
}

方法二

function _new2(fn, ...arg) {
   // 这一句话只是构造了一个对象,这个对象的__proto__=== fn.prototype
   var obj = Object.create(fn.prototype)
   // 并没有给这个对象赋值,将fn的this对象设置为obj
   // call 是列表, apply是数组
   const ret = fn.call(obj, ...arg) 
   // 为啥这里需要判断一下ret,根据new的定义,如果构造函数没有返回一个对象,那么返回this对象,this当前就是obj
   return ret instanceof Object ? ret : obj 
}

from daily-interview-question.

xiaoxixi6633 avatar xiaoxixi6633 commented on May 13, 2024
function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);
    const ret = fn.apply(obj, arg);
    return ret instanceof Object ? ret : obj;
}

还可以这么写

  obj.__proto__ = fn.prototype
  const result = fn.call(obj, ...args)
  return result instanceof Object ? result: obj
}

from daily-interview-question.

yangwanging avatar yangwanging commented on May 13, 2024

先理清楚 new 关键字调用函数都的具体过程,那么写出来就很清楚了

  1. 首先创建一个空的对象,空对象的__proto__属性指向构造函数的原型对象
  2. 把上面创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象
  3. 如果构造函数返回一个非基本类型的值,则返回这个值,否则上面创建的对象
function _new(fn, ...arg) {
    var obj = Object.create(fn.prototype);
    const result = fn.apply(obj, ...arg);
    return Object.prototype.toString.call(result) == '[object Object]' ? result : obj;
}

fn.apply(obj, ...arg);应该用call或者arg

from daily-interview-question.

calmchang avatar calmchang commented on May 13, 2024

请问大家,有用自己写的这个 _new 方法试过 _new(Number,123)或_new(String,"abc") 吗?

from daily-interview-question.

52javascript avatar 52javascript commented on May 13, 2024
function Person(name,age){
    this.name=name;
    this.age=age;
    this.sayName=function(){
        console.log(this.name);
    };
    return{
        name:this.name,
        age:this.age,
        sayName:this.sayName
    }
}

Person.prototype.sayHi=function(){
    console.log("I am "+this.name);
};

function foo() {
    let constructor = [].shift.apply(arguments)
    let obj = Object.create(constructor.prototype)
    let res = constructor.call(obj, ...arguments)
    if (typeof res === 'object') {
        res.__proto__ = obj.__proto__
        return res
    }
    if (typeof res === 'number' ||  typeof res === 'string') {
        return res
    }
    return obj
}

let a = foo(Person, 1, 2)
console.log(a.name)
console.log(a.age)
console.log(a.sayHi())


let b = foo(Number, 1)
console.log(b)

from daily-interview-question.

gaoxinxiao avatar gaoxinxiao commented on May 13, 2024

/**
* 实现**
* 1.首先创建一个对象
* 2.取到arguments的第一个参数也就是传进来的即将被实例化的函数赋值给Con
* 3.将Con.prototyp绑定到当前创建的obj的__proto__ 因为要访问构造函数里原型的属性
* 4.通过apply改变构造函数内部的指向
* 5.最后判断一下构造函数的返还参数 是否是对象
* */

    function $new() {
        var obj = new Object()
        Con = [].shift.call(arguments)
        obj.__proto__ = Con.prototype
        var res = Con.apply(obj, arguments)
        return res instanceof Object ? res : obj
    }

from daily-interview-question.

wjx25zj avatar wjx25zj commented on May 13, 2024
// method2
function myNew() {
    var [param1, args] = [...arguments];
    var target = {};
    target.__proto__ = Person.prototype
    var res = param1.call(target, args)
    if (res) {
        return res;
    } else {
        return target
    }
}

// method2
function myNew2() {
    var [param1, args] = [...arguments];
    var target = Object.create(Person.prototype)
    var res = param1.call(target, args)
    if (res) {
        return res;
    } else {
        return target
    }
}

//--------------------------------------------------------------------

function Person(name) {
    this.name = name;
}
Person.prototype.sayName = function () {
    console.log(this.name);
}
var per = myNew(Person, '张安');
// var per = myNew2(Person, '张安');
per.sayName();
console.log(per);


from daily-interview-question.

lunhui1994 avatar lunhui1994 commented on May 13, 2024
  1. 创建一个空对象obj。 (1,3可以使用const obj = Object.creat(fn.prototype))
  2. 原型继承。
  3. 构造函数继承。
  4. 返回对象(若构造函数中return了引用类型比如数组,对象等。new会返回该引用对象,否则将返回初始化之后的对象obj。)

from daily-interview-question.

Ke1vin4real avatar Ke1vin4real commented on May 13, 2024
function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);
    const ret = fn.apply(obj, arg);
    return ret instanceof Object ? ret : obj;
}
_new(Number, 1).toFixed(2) // Uncaught TypeError: Number.prototype.toFixed requires that 'this' be a Number

这个_new出来的对象调用原型上的方法会报错?

from daily-interview-question.

tjwyz avatar tjwyz commented on May 13, 2024

默写高赞...

function _new (fn , ...arg) {
    let obj = Object.create(fn.prototype);
    let ret = fn.apply(obj, arg);
    // 构造函数本就可以返回一个类对象...  
    // 手动返回基础类型时 or 正常不return时 才返回this
    // 
    // 但是fn不是构造函数... 就是正常执行下.. 为了和正常的构造函数保持一致所以修正一下
    return ret instanceof Object ? ret : obj;
}

from daily-interview-question.

zengkaiz avatar zengkaiz commented on May 13, 2024

new 都做了什么?
1、创建一个新的实例对象
2、将this指向新的实例对象
3、新对象的__proto__属性指向构造函数的原型对象
4、返回值
第一种实现:

function _new(Func, ...args){
  let obj = {}
  obj.__proto__ = Func.prototype
  let result = Func.call(obj, ...args)
 return (result!== null && /^(object)|(function)$/.test(typeof result)) ? result : obj
}

第二种实现:

function _new(Func, ...args){
 let obj = Object.create(Func.prototype)
 let result = Func.call(obj, ...args)
return (result!== null && /^(object)|(function)$/.test(typeof result)) ? result : obj
}

from daily-interview-question.

promotion-xu avatar promotion-xu commented on May 13, 2024
// 实现一个new
// 1. 创建一个空对象,并指向构造函数的原型
// 2. 将空对象指向构造函数的this, 用构造函数内部方法修改空对象
// 3. 如果构造函数返回一个非基本类型的值,则返回这个值,否则返回空对象

function Person(name, age) {
  this.name = name;
  this.age = age;
}

function _new(fn, ...args) {
  const obj = Object.create(fn.prototype);
  const result = fn.apply(obj, args);
  return result instanceof Object ? result : obj;
}

console.log(_new(Person, "xuzhen", "18"));

from daily-interview-question.

zuibunan avatar zuibunan commented on May 13, 2024

先理清楚 new 关键字调用函数都的具体过程,那么写出来就很清楚了

  1. 首先创建一个空的对象,空对象的__proto__属性指向构造函数的原型对象
  2. 把上面创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象
  3. 如果构造函数返回一个非基本类型的值,则返回这个值,否则上面创建的对象
function _new(fn, ...arg) {
    var obj = Object.create(fn.prototype);
    const result = fn.apply(obj, ...arg);
    return Object.prototype.toString.call(result) == '[object Object]' ? result : obj;
}

@Hiker9527
构造函数返回 String, Number, Boolean等对象也是可以的,而这些对象toString后并不是[object Object]

function _new(fn, ...arg) {
   var obj = Object.create(fn.prototype);
   const result = fn.apply(obj, ...arg);
   return result instanceof Object ? result : obj;
}

from daily-interview-question.

Jiujiuou avatar Jiujiuou commented on May 13, 2024
function _new(){
  const obj = {}
  const Constructor = Array.prototype.shift.call(arguments)

  obj.__proto__ = Constructor.prototype
  const result = Constructor.apply(obj, arguments)

  return typeof result === 'object' ? result : obj
}
// result 可能返回的是null,当result是null当时候就应该返回obj了,改一下你的代码
function _new(){
  const obj = {}
  const Constructor = Array.prototype.shift.call(arguments)

  obj.__proto__ = Constructor.prototype
  const result = Constructor.apply(obj, arguments)

  return typeof result === 'object' ? result || obj: obj
}

from daily-interview-question.

crush12132 avatar crush12132 commented on May 13, 2024

这个题的题目描述是啥...

from daily-interview-question.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.