实现call
function fn(q, w, e) {
console.log(this)
console.log(q, w, e)
return 888
}
var obj = {
name:"珠峰",
fn:888
}
Function.prototype.myCall = function (target, ...arg) {
// this ---> fn
let fn = this; // 把fn执行,然后把其中的this 换成target
let a = Symbol('mycall')
// target.fn(...arg)
target[a] = fn;
let res = target[a](...arg) // res是fn执行结果
delete target[a]
return res//myCall的执行结果就是fn的执行结果
}
let res1 = fn.call(obj, 1, 2, 3) // res1 --> 888
let res2 = fn.myCall(obj, 1, 2, 3) // res2 --> 888
/*
全局下的this是window
自执行函数this是window
事件绑定对应函数中的this是 绑定的元素
其他看点 点前边是谁this就是谁,没点就是window
new执行类的时候 其中的this是实例
类原型上的方法中的this得是实例
call可以改变函数中的this指向 f.call(111)
apply bind 都是改变函数中this指向的
箭头函数中的this是上级作用域中的this !!!!!
*/
Tab
<body>
<div id="box">
<header class='header'>
<button>111</button>
<button>222</button>
<button>333</button>
</header>
<main class='main'>
<div>111</div>
<div>222</div>
<div>333</div>
</main>
</div>
<div id="box2">
<header class='header'>
<button>111</button>
<button>222</button>
<button>333</button>
</header>
<main class='main'>
<div>111</div>
<div>222</div>
<div>333</div>
</main>
</div>
</body>
<script>
function Tab(id, option) {
this.box = document.getElementById(id);
this.btns = this.box.getElementsByTagName('button')
this.divs = this.box.getElementsByTagName('div')
this.option = option
}
Tab.prototype.bindEvent = function () {
// 负责给button 绑定点击事件
// this.btns
// this 实例
for (var i = 0; i < this.btns.length; i++) {
((m) => {
this.btns[i].onclick = () => {
// m 0 1 2
// 通过实例 调用 hideDiv
this.hideDiv(m)
}
})(i)
}
}
Tab.prototype.hideDiv = function (n) {
// 先隐藏所有div 然后再让对应div展示
// 形参n对应的是要展示的div的索引
for (let i = 0; i < this.divs.length; i++) {
this.divs[i].style.display = 'none'
}
this.divs[n].style.display = 'block'
}
Tab.prototype.init = function () {
// this.option
this.hideDiv(this.option.qqq)
this.bindEvent()
}
let tab1 = newTab('box', {
// 配置项
qqq:1// 默认进来选中第二项
})
tab1.init()
let tab2 = new Tab('box2', {
qqq:2
})
tab2.init()
</script>
Apply
function fn() {
console.log(arguments)
console.log(this)
}
var obj = {
name:"珠峰"
}
Function.prototype.myBind = function (target, ...arg) {
// arg [1,2,3,4,5]
// this -- > fn
let fn = this;
return function (...arg2) { // [6,7,8,9]
// 这个函数执行 就得让fn执行
return fn.call(target, ...arg, ...arg2)
}
}
// bind会返回一个新函数,新函数执行的时候,
// 会让fn执行,并且把fn中的this换成obj,后边的12345是传给fn的实参
// 新函数执行的时候 给新函数传递的实参 会连接到12345的后边
let res1 = fn.myBind(obj, 1, 2, 3, 4, 5)
res1(6, 7, 8, 9)
// 让fn执行 并且把fn本次执行中的this换成obj,后边的12345是传递给fn的实参
// let res2 = fn.call(obj, 1, 2, 3, 4, 5)
// call 不能改变this的情况: 1-箭头函数 2-bind的返回函数
</script>
<script src=''>
/*
f.call (obj,1,2,3)
let res = f.apply(obj,[1,2,3])
apply的功能和call一样;区别在于 call执行的时候 给函数传参是散开写的
apply执行的时候 给函数传参是一个集合的方式
*/
Function.prototype.myApply = function (target, arg) {
// this --> fn
let fn = this;
let a = Symbol('myapply') =
target[a] = fn
let res = target[a](...arg)
delete target[a]
return res
}
function fn() {
// console.log(this)
console.log(arguments)
}
fn([1, 2, 3, 4])
// fn.call(null, 1, 2, 3, 4)
fn.apply({
name:"珠峰"
}, [1, 2, 3, 4])
// var ary = [12, 32, 454, 56, 67868]
// Math.max(...ary) //===Math.max(12,32,454,56,67868)
// Math.max.apply(Math, ary)
Create
var obj = new Object();
var obj2 = {};
var obj3 = Object.create([]) // 创造一个对象,对象的__proto__是指向这个空数组的,返回这个对象
// Object.create 执行会返回一个空对象,这个对象的__proto__ 是指向create的参数
console.log(obj, obj2, obj3)
function create(target) {
// let a = {};
// a.__proto__ = target;
// return a
function QQQ() {}
QQQ.prototype = target; // 原型重写
let a = newQQQ;
return a
}
var obj4 = create([])
Class
/*
函数的三种角色:
普通函数
对象
类
*/
</script>
<script src=''>
/*
function Person(name,age,sex){
this.name = name;
this.age = age
this.sex = sex
}
Person.prototype.eat = function(food){
console.log(`吃${food}`)
}
Person.prototype.yy = 100
Person.ttt = 888;// 静态属性
new Person
Person()
*/
// es6新增的一个用来创造类的方式 创造出来的类不能当作普通函数执行;
// 类的原型上一般都是放的函数;
class Person {
// constructor 是class规定的名字
constructor(name, age, sex) {
console.log(arguments)
this.name = name;
this.age = age;
this.sex = sex;
}
height = {} // 私有属性的简写方式
eat(food) {
console.log(`吃${food}`)
}
play() {}
study() {}
static qqq = 888// 静态属性 指的就是Person自己属性
static ttt = 999// Person的prototype是他的一个内置的静态属性
static yyy = 666
}
Person.prototype.aaa = 888
let p1 = new Person("小孔", 12, 0)
若有收获,就点个赞吧