Skip to content

Latest commit

 

History

History
385 lines (270 loc) · 7.72 KB

查看this输出和原型链输出的系列问题.md

File metadata and controls

385 lines (270 loc) · 7.72 KB

查看this输出和原型链输出的系列问题

查看this输出和原型链输出的系列问题

第一题 (得分💯)

var length = 10;

// 函数
function fn() {
  return this.length + 1; 
}

// 对象
var obj = {
  length: 5,
  test1: function() {
    return fn();
  }
};

// 对象属性赋值为函数 fn()
obj.test2 = fn;

// 当一个对象的属性调用函数,返回fn(),fn()作用域为全局,返回 11
console.log(obj.test1.call());

// 对象的属性调用函数返回 fn(),全局,返回11
console.log(obj.test1());

// 函数fn()的调用 11,参数空,指向全局
console.log(obj.test2.call());

// 对象属性调用一样, 内部的属性,所以为6
console.log(obj.test2());

第二题(得分💯)

// 试试chrome挂载, number为2
window.number = 2;

var obj = {
 number: 3,
 db1: (function(){
   console.log(this);
   this.number *= 4;
   return function(){
     console.log(this);
     this.number *= 5;
   }
 })()
}

// 立即调用函数表达式
//  返回一个函数
var db1 = obj.db1; // 外部的 2 * 4 = 8
db1(); // 外部的 8 * 5 = 40
// 对象调用内部的this, obj.number 变了15
obj.db1();

// 直接看这 对象的属性
console.log(obj.number);   // 15
console.log(window.number); // 40

第三题(得分💯)

function foo(something){
    this.a = something
}

var obj1 = {
    foo: foo
}

var obj2 = {}

// obj1调用foo函数,在内部
obj1.foo(2); 

// obj1.a 上面赋值后为 2
console.log(obj1.a);  // 2

// 指向obj2对象
obj1.foo.call(obj2, 3);

// 赋值后为3
console.log(obj2.a); // 3

// 创建新对象赋值 a: 4
var bar = new obj1.foo(4)

// 2
console.log(obj1.a);  // 2

// 4
console.log(bar.a); // 4

第四题(得分💯)

var name = "window";

var person = {
  name: "person",
  sayName: function () {
    console.log(this.name);
  }
};

function sayName() {
  // 赋值函数
  var sss = person.sayName;
  sss(); // window
  // 对象指向返回 person
  person.sayName();  // person
  (person.sayName)(); // 立即执行,同上 person 
  (b = person.sayName)(); // 赋值后执行, window
}

sayName();

第五题(得分💯)

var name = 'window'

var person1 = {
  name: 'person1',
  foo1: function () {
    console.log(this.name)
  },
  foo2: () => console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}

var person2 = { name: 'person2' }

// 对象属性调用 
person1.foo1();  // person1
// 指向对象persson2
person1.foo1.call(person2); // person2

// 对象调用,箭头函数指向外面
person1.foo2();  // window
person1.foo2.call(person2);  // 箭头函数还是指向外面 window

// ()() 有两个?不怕嘛,一个个看
// 第一次调用返回函数,调用外面执行
person1.foo3()();  // window

// person1.foo3 以为是person1,但是是绑定了person2,但里面返回函数,指向外面
person1.foo3.call(person2)();  // window
// person1.foo3() 执行返回函数, call绑定person2对象了哦
person1.foo3().call(person2);  // person2

// ()() person1.foo4() 返回一个箭头函数,注意是person1里面的
person1.foo4()();  // person1

// person1.foo4的时候绑定了 person2,箭头函数是指向person2
person1.foo4.call(person2)();  // person2

// person1.foo4() 这个时候是person1 绑定也没用,箭头函数指向person1
person1.foo4().call(person2);  // person1

第六题(得分💯)

var name = 'window'

function Person (name) {
  this.name = name
  this.foo1 = function () {
    console.log(this.name)
  }
  this.foo2 = () => console.log(this.name)
  this.foo3 = function () {
    return function () {
      console.log(this.name)
    }
  }
  this.foo4 = function () {
    return () => {
      console.log(this.name)
    }
  }
}

var person1 = new Person('person1')
var person2 = new Person('person2')

// 题在这,person1实例,就看对象好了

// person1调用
person1.foo1()  // person1
// 绑定了person2
person1.foo1.call(person2)  // person2

// 箭头函数,指向外面的person1
person1.foo2()  // person1
// 箭头函数指向外面的person1,绑定没用
person1.foo2.call(person2)  // person1

// person1.foo3() 返回函数,到了最外层
person1.foo3()()  // window

// person1.foo3 对象person1调用,绑定了person2对象实例,在最外层
person1.foo3.call(person2)() // window

// person1.foo3() 返回了函数,函数绑定了person2
person1.foo3().call(person2) // person2

// person1.foo4() 返回箭头函数,但这个时候this指向person1
person1.foo4()()  // person1

 // 先绑定person2 ,箭头函数指向person2
person1.foo4.call(person2)() // person2

// 返回箭头函数指向person1 ,所以为person1
person1.foo4().call(person2)  // person1


var obj = {
  name: "obj",
  foo: function() {

  }
}

第七题(得分💯)

var name = 'window'

function Person (name) {
  this.name = name
  this.obj = {
    name: 'obj',
    foo1: function () {
      return function () {
        console.log(this.name)
      }
    },
    foo2: function () {
      return () => {
        console.log(this.name)
      }
    }
  }
}

var person1 = new Person('person1')
var person2 = new Person('person2')

// 题在这

// person1.obj.foo1() 返回一个函数,到最外面指行,指向window
person1.obj.foo1()()  // window

//  person1.obj.foo1.call(person2) 绑定了person2,返回函数 ,执行
person1.obj.foo1.call(person2)()  // window

// 返回函数,再次被绑定person2 
person1.obj.foo1().call(person2)  // person2

//  person1.obj.foo2() 返回箭头函数,执行执行 obj
person1.obj.foo2()()  // obj

// person1.obj.foo2 绑定了person2 ,外面是啥,外面是this.name = 'person2'
person1.obj.foo2.call(person2)()  // person2

// person1.obj.foo2() ,箭头函数执行 obj
person1.obj.foo2().call(person2)  // obj

第八题(得分💯)

// 当函数的参数有默认值时, 会形成一个新的作用域, 这个作用域用于保存参数的值(所以不会修改全局的变量)
var x = 0

// x 参数1 , y 是函数
function foo(x, y = function() { x = 3; console.log(x) }) {
  // 带入参数1
  console.log(x)  // 1
  var x = 2
  console.log(x) // 2
  // 函数调用, x为3
  y()  // 3
  // 不要以为是3,作用域问题
  console.log(x) // 2
}

foo(1)
// foo(1),1是内部作用域1,内部赋值2,也是内部的事
console.log(x) // 0

第九题(得分💯)

Function.prototype.a = function () {
  console.log("我是a");
};
Object.prototype.b = function () {
  console.log("我是b");
};

function A() {}
var c = new A();

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

// 是个函数
A.a(); // 我是a
// 函数即对象,往上找
A.b(); // 我是b

// c是实例对象 没有a属性 c.a不是函数
c.a(); // 报错,不是函数

// c是对象
c.b(); // 我是b

// 函数 -> 对象  Function 构造函数对象
Function.b();  // 我是b

// 对象 Object构造函数
Object.a();  // 我是a

第十题

请用你的语言来描述原型链和this指向的相关概念~

原型链 其基本思想就是通过原型继承多个引用类型的属性和方法

this指向 在标准函数中,this 引用的是把函数当成方法调用的上下文对象,这时候通常称其为 this 值

在箭头函数中,this引用的是定义箭头函数的上下文