frontend-interview icon indicating copy to clipboard operation
frontend-interview copied to clipboard

如果一个构造函数,bind了一个对象,用这个构造函数创建出的实例会继承这个对象的属性吗?为什么?

Open su37josephxia opened this issue 3 years ago • 35 comments

su37josephxia avatar Dec 21 '21 06:12 su37josephxia

占坑

su37josephxia avatar Dec 25 '21 00:12 su37josephxia

  let person = {
    name: "qzy",
  };
  function Person(age) {
    this.age = age;
  }

  let bindFn = Person.bind(person);

  // 实例
  let p = new bindFn(18);
  console.log(p); // Person {age: 18}
  • 不会继承
  • 因为根据 this 绑定四大规则
    • 默认绑定
    • 隐式绑定
    • 显式绑定
    • new绑定
  • new 绑定的优先级高于 bind 显示绑定
  • 通过 new 进行构造函数调用时,会创建一个新对象,这个新对象会代替 bind 的对象绑定,作为此函数的 this
  • 并且在此函数没有返回对象的情况下,返回这个新建的对象

qzyqzy avatar Jan 03 '22 03:01 qzyqzy

不会继承,因为根据 this 绑定四大规则,new 绑定的优先级高于 bind 显示绑定,通过 new 进行构造函数调用时,会创建一个新对象,这个新对象会代替 bind 的对象绑定,作为此函数的 this,并且在此函数没有返回对象的情况下,返回这个新建的对象

yanzefeng avatar Jan 03 '22 03:01 yanzefeng

不会继承,因为new 绑定的优先级高于 bind 绑定。new 时会创建一个新的对象返回,所以不会继承

oujinlong avatar Jan 03 '22 08:01 oujinlong

不会继承

js 中 this 的绑定规则分为4种:

  • 默认绑定
  • 隐式绑定
  • 显式绑定
  • new 绑定 优先级从高到低为 new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

bind绑定属于 显式绑定,用构造函数创建实例属于 new绑定,优先级较高 使用 new进行构造函数调用时,会创建一个新对象,这个对象会代替 bind 的对象绑定,作为此函数的 this

rachern avatar Jan 03 '22 09:01 rachern

如果一个构造函数,bind了一个对象,用这个构造函数创建出的实例会继承这个对象的属性吗?为什么

  • 不会
    1. 先来看下执行顺序 先bindnew 实例化, 之前我们讲过的new 会自动生成一个新对象 或者return 一个引用类型, 所以不管bind 怎么改变执行的上下文环境 都没法影响到 new 的实例化操作
    2. 当然假设我们实例化的对象 假设有一个function 可以通过bind 改变 这个方法执行的上下文环境
function Foo() {
  this.name = 'foo'
}

Foo.prototype.fn = function () {
  console.log(this.name)
}

const obj = {
  name: 'obj'
}

const foo = new (Foo.bind(obj))()

console.log(foo)

foo.fn.bind(obj)()

xyz-fish avatar Jan 03 '22 10:01 xyz-fish

bind() 方法会创建一个新函数,当这个新函数被调用时,它的 this 值是传递给 bind() 的第一个参数, 它的参数是 bind() 的其他参数和其原本的参数。 语法是这样样子的: fun.bind(thisArg[, arg1[, arg2[, ...]]])

  • thisArg 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用 new 操作符调用绑定函数时,该参数无效。
  • arg1, arg2, … (可选)当绑定函数被调用时,这些参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数。

`let obj = { name:"obj", prot:"toBind" }

function Instance(){ this.attr = "art" }

let bindObj = Instance.bind(null,obj); let ins = new bindObj(); console.log(ins)//Instance { attr: 'art' }`

结论:并不会继承这个对象的属性,因为当使用 new 操作符调用绑定函数时,thisArg(即这里的obj)参数无效。

wzl624 avatar Jan 03 '22 10:01 wzl624

不会 因为new的绑定优先级高于bind绑定的优先级 this的绑定优先级 默认绑定 隐式绑定 显式绑定 new绑定

zzzz-bang avatar Jan 03 '22 11:01 zzzz-bang

不会,因为this的绑定四大规则

  • 默认绑定(非严格模式下this执向window,严格模式指向空对象{})
  • 隐式绑定(类似setTimeout以及对象内非箭头函数中,this都是指向window)
  • 显示绑定(call, apply, bind)
  • new 绑定 四个规则优先级:new>显示>隐式>默认,通过new 调用构造函数时,会创建一个新的对象,这个新的对象会替代bind的对象绑定,这个时候如果此函数中的this,在没有返回对象的情况下,就会返回这个新对象。

QbjGKNick avatar Jan 03 '22 11:01 QbjGKNick

不会 new 运算符 绑定的的this优先级最高 js 中 this 的绑定规则分为4种: 默认绑定 隐式绑定 显式绑定 new 绑定 优先级从高到低为 new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

chunhuigao avatar Jan 03 '22 11:01 chunhuigao

结论

不会继承

说明

new 绑定的优先级高于 bind 显示绑定,通过 new 进行构造函数调用时,new运算符绑定的this优先级最高 分别是 new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

bianxuerui avatar Jan 03 '22 12:01 bianxuerui

结论

不会继承

绑定优先级 new 绑定 > 显示绑定 > 隐式绑定 > 默认绑定

bind绑定属于 显式绑定,用构造函数创建实例属于 new绑定,所以不会继承

qytayh avatar Jan 03 '22 13:01 qytayh

function Person(name) {
 this.name = name;
}
let p = {
    age: "32",
};
var bindPerson = Person.bind(p);
console.log(new bindPerson("song"));

new绑定优先级高于bind的显示绑定,最后this还是交给new出来的实例对象

superjunjin avatar Jan 03 '22 13:01 superjunjin

new操作会先创建一个对象并绑定 this 实现构造函数的继承,绑定操作先改变了this的指向,而bind中绑定的操作,会根据当前this的指向而绑定不同的对象,也就是bind函数的第一个参数,所以bind不会继承

alienRidingCat avatar Jan 03 '22 13:01 alienRidingCat

如果一个构造函数,bind了一个对象,用这个构造函数创建出的实例会继承这个对象的属性吗? 答: 在this层不会继承。 函数中的return除非返回的是个对象,否则通过new返回的是个this,指向一个空对象,空对象原型指向foo.prototype,空对象的b属性是100。也就是说通过new的方式创建一个对象,bind()函数在this层面上并不起作用,但是在参数层面上仍起作用。

this 层 ` function foo() { this.b = 100; console.log(this.a); debugger return this.a; }

var func =  foo.bind({a:1});
func();//1
new func();//undefined   {b:100},可以看到此时上面的bind并不起作用

**参数层** function foo(c) { this.b = 100; console.log(this.a); console.log(c); return this.a; }

var func =  foo.bind({a:1},20);
new func();//undefined 20,通过new创建对象func,bind绑定的c依旧起作用

` this 绑定的优先级

优先级:new 绑定 > 显示绑定 > 隐式绑定 > 默认绑定

所以 this 的判断顺序:

new 绑定: 函数是否在 new 中调用?如果是的话 this 绑定的是新创建的对象; 显式绑定: 函数是否是通过 bind、call、apply 调用?如果是的话,this 绑定的是指定的对象; 隐式绑定: 函数是否在某个上下文对象中调用?如果是的话,this 绑定的是那个上下文对象; 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到全局对象。

partiallove avatar Jan 03 '22 13:01 partiallove

结论:

不会继承

描述:

  • 根据构造函数内,this绑定的四大原则,bind传入对象属于显示绑定,优先级低于new 绑定。我们在new一个构造函数,产生实例的时候,会产生一个新对象,并代替bind传如的对象和this绑定,并在构造函数没有返回别的对象的时候返回这个对象。

  • this绑定的四大原则: 默认绑定:没有任何修饰符(bind,call等),非严格模式下this指向window,严格模式下指向undifined。比如函数直接被调用 隐式绑定:函数调用时候,上下文,或者被某个对象拥有,this会指向这个调用的上下文。比如,某函数作为某对象的属性。 显示绑定:bind,call,apply传入对象,this会指向这个传入对象 new 绑定:创建一个新对象,并把this指向这个对象。 绑定的优先级:New 绑定 > 显示绑定 > 隐式绑定 > 默认绑定

所以:如果new一个构造函数的时候,发生了bind显示绑定,new创建的新对象会代替bind传入的对象,与this进行绑定。导致返回的对象,不会发生bind继承。

JanusJiang1 avatar Jan 03 '22 13:01 JanusJiang1

不会继承,因为new 运算符 绑定的的this优先级高于显式绑定。 js 中 this 的绑定规则分为4种: 优先级从高到低为 new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

attackam avatar Jan 03 '22 14:01 attackam

不会继承。

js中this的绑定分为4中:

  1. 默认绑定,独立的调用,指向window
  2. 隐式绑定,函数在对象内,被对象调用,指向调用者
  3. 显示绑定,指向显示绑定者
  4. new绑定,指向新创建的对象

优先级为 new绑定 > 显示绑定 > 隐式绑定 > 默认绑定

这里用构造函数创建示例是属于new绑定,内部this会指向这个新创建的对象,而不会被bind影响。

crazyyoung1020 avatar Jan 03 '22 14:01 crazyyoung1020

不会继承 绑定优先级: new > 显示绑定(bin, call, apply) > 隐式绑定(某对象的函数调用会绑定该对象) > 默认绑定(直接调用函数严格模式下undefined,非严格this是window)

jiafei-cat avatar Jan 03 '22 14:01 jiafei-cat

不会继承。因为根据this绑定四大规则,new绑定的优先级高于bind显示绑定,通过new进行构造函数调用时,会创建一个新对象,这个新对象会代替bind的对象绑定,作为函数的this,并且在此函数没有返回对象的情况下,返回这个新建的对象

kossfun avatar Jan 03 '22 14:01 kossfun

不会继承 在js中的4种绑定中,new绑定大于bind的显式绑定,在bind中,会判断函数是否是被 new 调用,如果是的话就会使用新创建 的 this 替换硬绑定的 this。

yaoqq632319345 avatar Jan 03 '22 14:01 yaoqq632319345

不会,new绑定优先级高于bind

alec1815 avatar Jan 03 '22 15:01 alec1815

答案:不会继承 this绑定的四大规则: 1、默认绑定 2、隐式绑定 3、显示绑定 4、new绑定 this绑定的四大规则优先级为: new > 显示绑定 > 隐式绑定 > 默认绑定

bind方法属于显示绑定,根据this绑定四大规则,new绑定的优先级高于bind显示绑定,通过new进行构造函数调用时会创建一个新对象,这个新对象会代替bind的对象绑定,作为此函数的this。所以不会继承

8023nana avatar Jan 03 '22 15:01 8023nana

不会继承,因为根据 this 绑定四大规则,new 绑定的优先级高于 bind 显示绑定,通过 new 进行构造函数调用时,会创建一个新对象,这个新对象会代替 bind 的对象绑定,作为此函数的 this,并且在此函数没有返回对象的情况下,返回这个新建的对象

792472461 avatar Jan 03 '22 15:01 792472461

不会继承, bind方法会创建一个新的函数实例,其 this 值会被绑定到传给 bind()的对象。new一个函数也会创建一个对象,如果是在函数执行时调用bind可以有效的将函数实例的this值绑定到传给 bind的对象上,但是new 一个构造函数他会返回一个新对象代替bind的对象绑定。new的优先级要大于bind

Limeijuan avatar Jan 03 '22 15:01 Limeijuan

答案

不会。

原因

JavaScriptthis 绑定形式共 4 种,
优先级从高到低为 new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

bind绑定 属于 显式绑定,用构造函数创建实例属于 new绑定,所以构造函数创建实例的 this 绑定优先级高于 bind绑定,所以不会去继承 bind绑定 的对象的属性。

const obj = {
  height:180
}
function Create(name='snail'){
  this.name = name;
  this.age = 18;
  this.hobby = 'code'
}
const instance = new (Create.bind(obj))();
console.log(instance); // { name: 'snail', age: 18, hobby: 'code' }

zhenyuWang avatar Jan 03 '22 15:01 zhenyuWang

如果一个构造函数,bind了一个对象X,用这个构造函数创建出的实例是不会继承X对象的属性的。

因为bind的作用是指定一个函数的this本地变量,那么,在语言设计者设计bind的时候就没有允许bind去指定构造函数的this,那么也就不会有之后的任何效果。

rhythm022 avatar Jan 03 '22 15:01 rhythm022

如果一个构造函数,bind了一个对象,用这个构造函数创建出的实例不会继承这个对象的属性,因为通过new构造函数的时候会创建一个简单的空对象,并且把这个对象作为this的上下文

liangle avatar Jan 03 '22 15:01 liangle

结论:实例不会继承

  • new 构造实例是将函数中的this绑定到新建的对象上并返回这比直接bind的优先级要高
  • this绑定优先级: new > 显示绑定(call,apply,bind)> 隐式绑定(根据函数调用的上下文) > 默认绑定(this指向全局)

jj56313751 avatar Jan 03 '22 15:01 jj56313751