Function.prototype.myApply = function (context) {
if (typeof this !== 'function') throw new TypeError("Error");
let result = null;
context = context || window;
context.fn = this;
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn;
return result;
}
Function.prototype.myCall = function (context) {
if (typeof this !== 'function') throw new TypeError("Error");
let result = null;
context = context || window;
context.fn = this;
const args = [...arguments].slice(1);
result = args.length
? context.fn(...args)
: context.fn()
delete context.fn;
return result
}
Function.prototype.myBind = function (context) {
if (typeof this !== 'function') throw new TypeError("Error");
const args = [...arguments].slice(1);
context = context || window;
// 这里不需要再把this作为context对象的方法调用,我们只需要保存调用bind方法的函数就可以
// 因为在bind返回的函数调用的时候需要根据是否是构造函数改变this绑定,在那个时候再去绑定
// 这里设置context.fn = this 实际是多余的
const fn = this;
return function Fn() {
return fn.apply(
this instanceof Fn
? this
: context,
args.concat(...arguments)
)
}
}
// new 操作
function newObj(fn) {
// 创建一个对象,把他的原型设置为构造函数的原型
const obj = Object.create(fn.prototype);
// 执行构造函数方法,把this绑定到新创建的对象
const result = fn.apply(obj, [...arguments].slice(1));
// 如果构造函数返回一个引用类型就返回构造函数的返回结果,否则返回新创建的对象
return typeof result === 'object' ? result : obj
}
function ts(a, b) {
console.log(this.age)
console.log(a)
console.log(b)
return 'cc'
}
// console.log(ts.myApply({ age: 20 }, [888, 202]))
// console.log(ts.myCall({age: 3}, 'big', '30'))
const b = ts.myBind({age: 666}, 'a')
b('b')
function Person(name, age) {
this.name = name;
this.age = age;
}
// const p = newObj(Person, 'cc', 18)
// console.log(p)
// console.log(p.__proto__ === Person.prototype)
console