Skip to content

面向对象/原型和原型链

参数传递

按值传递

把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样

  • 基本类型是传递的拷贝
  • 引用类型传递的是地址

手写call apply

js
var Obj = {
    name: 123
}
function a() {
    console.log(this.name)
}
a() // undefined
a.call(Obj) // 123

call 方法用于调用一个函数,同时指定this的值。当你手写一个call方法时,需要注意以下几个关键点:

  1. 正确设置this值: call方法的第一个参数是this的值,它应该被设置为调用call方法的函数内部的this值。
  2. 参数传递: call方法接受一个参数列表,这些参数应该被传递给目标函数。
  3. 函数调用: 使用apply方法或者直接调用函数,并传递正确的参数。
  4. 非函数参数处理: 如果传入的不是一个函数,应该抛出TypeError。
  5. 返回值: call方法应该返回函数的调用结果。
  6. 确保函数是可调用的: 确保传入的函数是可调用的,如果不是函数,应该抛出错误。
  7. 确保参数是数组: call方法接受的参数应该是一个列表,如果传入的不是数组,应该将其转换为数组。 this总是指向的是被调用的对象,所以调用 call 的时候 this 的指向是 function,所以需要把当前函数复制到目标对象里面进行执行这样 this 的指向就是目标对象了,当目标对象为 null的时候默认就是 window
js
Function.prototype.mycall = function(context, ...args){
    if(typeof this ! == 'function') {
        throw new TypeError('TypeError: myCall is not a function')
    }
    const _this = context || window; // 指向的是目标
    const fnSymbol = Symbol()
    _this[fnSymbol] = this;
    const result = _this[fnSymbol](...args);
    delete _this[fnSymbol];
    return result;
}

实现自定义call

call 方法是一个函数对象的实例方法,它允许你调用一个函数,并将上下文(this 值)设置为提供的值,同时传递给函数任意数量的参数

  • 把函数设置为对象属性
  • 执行函数
  • 删除函数

call和apply的区别

  • call 方法接受一系列参数,每个参数都是单独传递的。
  • apply 方法接受一个数组,数组中的所有元素作为参数传递。

手写bind

bind() 方法会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。 由此我们可以首先得出 bind 函数的两个特点:

  1. 返回一个函数;
  2. 可以传入参数;
js
Function.prototype.bind2 = function(context, ...args) {
    const _this = this;
    return function() {
        return _this.apply(context, ...args)
    }
}