实现 call
Function.prototype.calls = function(cont){
cont = cont || window //不传cont默认为window
cont.demo = this
let args = [...arguments].slice(1) //获取传参
let ret = cont.demo(...args) //进行了隐式绑定,具体可看我讲隐式绑定的文章了解
delete cont.demo //销毁临时变量
return ret
}
var name = "windows"
var obj = {
name: "obj",
fn: function(names){
console.log(this.name,names)
}
}
obj.fn("fn") //obj fn
obj.fn.call(this,"call") //windows call
obj.fn.calls(this,"calls") //windows calls
实现 apply
apply与call的区别就只有传参不同,apply是传入数组,call是多个变量的传入
Function.prototype.applys = function(cont,arr){
cont = cont || window //不传cont默认为window
cont.demo = this
let ret = cont.demo(...arr)
delete cont.demo //销毁临时变量
return ret
}
var name = "windows"
var obj = {
name: "obj",
fn: function(names){
console.log(this.name,names)
}
}
obj.fn("fn") //obj fn
obj.fn.apply(this,["apply"]) //windows call
obj.fn.applys(this,["applys"]) //windows calls
实现 bind
bind与前面两个不同之处就是,bind返回的是一个函数
Function.prototype.binds = function(cont){
let that = this
let args = [...arguments].slice(1)
return function fn(){
//concat是为了合并参数
return that.apply(cont,args.concat(...arguments))
}
}
var name = "windows"
var obj = {
name: "obj",
fn: function(names){
console.log(this.name,names)
}
}
//测试
obj.fn("fn") //obj fn
obj.fn.bind(this,"bind")() //windows bind
obj.fn.binds(this,"binds")() //windows binds
实现 new
new关键词主要做了4个操作
- 生成一个新对象
- 新对象链接到原型
- 新绑定函数调用的
this
- 如果函数没有返回其他对象,则返回这个新对象
function news(cont){
let obj = {}
obj.__proto__ = cont.prototype
let demo = cont.apply(obj,[...[...arguments].slice(1)])
return typeof demo == "object"?demo:obj
}
//测试
function classs(value){
this.value = value
}
classs.prototype.test = function(){
console.log(this.value)
}
var aaa = new classs("aaaaaaa")
var bbb = news(classs,"bbbbbb")
console.log(aaa)
console.log(bbb)
实现 Object.create()
function objectCreate(o){
function fn(){};
fn.prototype = o;
return new fn();
}
//测试
var demo = {
a:1
}
var demos1 = Object.create(demo);
var demos2 = objectCreate(demo);
console.log(demos1)
console.log(demos2)
如有有疑问的地方,欢迎留言