手写instanceof
instanceof
- instanceof 运算符用于检测构造函数的prototype属性 是否在某个实例对象的原型链上
- 可以判断继承关系 只要是在同一条原型链上 就返回true
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
class Proson {
constructor(name, age) {
this.name = name
this.age = age
}
}
class Student extends Proson {
constructor(name, age, sex) {
super(name, age)
this.sex = sex
}
}
let zhangsan = new Student("zhangsan", 18, "男")
function myInstanceof(obj1, obj2) {
let objproto = obj1.__proto__//记录传进来的实例对象的__proto__属性
while (true) {
// 如果 传进来的实例对象的__proto__属性 === null 就证明不在一个原型链上直接返回false
if (objproto === null) {
return false
} else if (objproto === obj2.prototype) { //如果实例对象的__proto__属性 === 构造函数的prototype属性直接返回true
return true
}
// 继续向上找 每次循环完把新的__proto__属性赋值给变量
objproto = objproto.__proto__
}
}
console.log(myInstanceof(zhangsan, Object));
console.log(myInstanceof(zhangsan,Proson));
console.log(zhangsan);
</script>
</body>
</html>
this不同场景如何取值
this易混场景
- 普通函数下的this
- call applay bind中的this
- 定时器中的this
- 箭头函数中的this
场景1 普通函数下的this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 普通函数的this
// 非严格模式下this指向是window
// 严格模式下this指向是undefined
// "use strict"
function a(){
console.log(this);
}
a()
</script>
</body>
</html>
场景2 call apply bind中的this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// call apply bind this指向
//情况1 this===>window
function a (){
console.log(this);
}
//a.call()//window
//a.call(undefined)//window
//a.call(null)//window
//情况2 传什么this就指向什么
let fn = a.bind({x:101})
fn()
a.apply("")
a.call(123)
</script>
</body>
</html>
场景3 定时器中的this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 情况1 settimeout + function this===>window
// 情况2 settimeout + 箭头函数 this===>上层作用域的this
setTimeout(function(){
console.log(this);
},100)
function fn(){
setTimeout(function(){
console.log(this);
},100)
}
fn.call({x:100})//window
// 情况2 指向上层作用域的this
class Obj{
fn(){
setTimeout(()=>{
console.log(this);
},100)
}
}
let o = new Obj()
o.fn()
function fn(){
setTimeout(()=>{
console.log(this);
})
}
fn.call({x:200})
</script>
</body>
</html>
场景4 箭头函数中的this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>test</button>
<script>
// 箭头函数中的this
//情况1:有function作用域的this指向上层this
//情况2:没有function作用域的this指向window
//情况1
class Obj{
say = ()=>{
console.log(this);
}
}
let obj = new Obj()
obj.say()//指向obj类
//情况2
const obj2 = {
say:()=>{
console.log(this);
}
}
obj2.say()//指向window
const btn = document.querySelector("button")
btn.onclick = ()=>{
console.log(this);//没有function作用域 所以指向window
}
btn.onclick = function(){
console.log(this);//有function作用域所以指向button按钮
}
</script>
</body>
</html>
面试题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const fn = {
x:123,
show(){
setTimeout(()=>{ //箭头函数的this指向上层
console.log(this.x);
},100)
}
}
fn.show()//123
fn.show.call({x:100})//100
</script>
</body>
</html>
手写bind函数
知识点
- function.prototype.mybind
- Array.prototype.slice.call()
- array.sshift()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=\, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function fn(a, b, c) {
console.log(this);
console.log(a, b, c);
return "this is fun"
}
// let cc = fn.bind({x:100})
// console.log(cc());
//手写bind
Function.prototype.mybind =function(){
let fn = this
let arg = Array.prototype.slice.call(arguments)
let _this = arg.shift()
return function(){
return fn.apply(_this,arg)
}
}
const cb = fn.mybind({x:200,y:200},1,2,3)
cb()
console.log(cb());
</script>
</body>
</html>