手写instanceof
出题目的
- 考察原型链的理解
知识点
instanceof
- instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
- 可以判断继承关系,只要是在同一条原型链上,就可以返回true
参考答案
while (true) {
if (obj1Proto === null) {
return false;
} else if (obj1Proto === obj2Prototype) {
return true;
}
obj1Prto = obj1Proto.__proto__;
}
this不同场景,如何取值?
this 易混场景
- 普通函数下的this
- call apply bind的this
- 定时器中的this
- 箭头函数中的this
测试题
// 题目1
let obj = {
x: 123,
show() {
setTimeout(() => {
console.log(this.x);
}, 100);
},
};
obj.show();
obj.show.call({x:100})
// 题目2
let obj = {
fn: () => {
console.log(this, 999);
},
};
obj.fn();
演示代码
情况1:
o 是 new 实例化来的,有单独的作用域
class Obj {
say = () => {
console.log(this); // this -> Obj
};
}
const o = new Obj();
o.say();
const oBtn = document.getElementById("btn");
oBtn.onclick = function () {
console.log(this);
};
手写bind函数
知识点
- Function.prototype.myBind
- Array.prototype.slice.call()
- array.shift()
演示代码
<!DOCTYPE html>
<html>
<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>@说人话的前端 - bilibili</title>
</head>
<body></body>
<script>
function fn(a, b, c, d) {
console.log(this);
console.log(a, b, c, d);
return "this is return";
}
// const cb = fn.bind({ x: 100 }, 1, 2, 3);
// console.log(cb());
// 手写bind
Function.prototype.myBind = function () {
const fn = this;
const arg = Array.prototype.slice.call(arguments);
const _this = arg.shift();
return function () {
return fn.apply(_this, arg);
};
};
const cb = fn.myBind({ x: 300 }, 1, 2, 3, 4);
console.log(cb());
</script>
</html>
谈谈闭包和闭包使用场景
什么是闭包
概念:闭包是作用域的一种特殊应用
触发闭包的情况
1、函数当做返回值被返回
2、函数当做参数被传递
3、自执行匿名函数
闭包的应用
1、隐藏变量
2、解决 for i 的问题
作用域
全局作用域、局部作用域
自由变量
不在自己作用域里的变量,就是自由变量
自由变量的值:在函数定义的地方向上层作用域查找。与函数调用位置无关
演示代码
<!DOCTYPE html>
<html>
<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>@说人话的前端 - bilibili</title>
</head>
<body></body>
<script>
// 情况1:函数当做返回值被返回
// function fn() {
// const a = 1;
// return function () {
// console.log(a);
// };
// }
// const a = 5;
// const cb = fn();
// cb();
// 情况2:函数当做参数传递
// function fn(cb) {
// const a = 100;
// cb();
// }
// const a = 500;
// fn(function () {
// console.log(a);
// });
// 情况3:自执行匿名函数
(function (index) {
console.log(index);
})(10);
</script>
</html>
<!DOCTYPE html>
<html>
<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>@说人话的前端 - bilibili</title>
</head>
<body>
<button>0</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</body>
<script>
const aBtn = document.getElementsByTagName("button");
// for (var i = 0; i < aBtn.length; i++) {
// (function (index) {
// aBtn[i].onclick = function () {
// console.log(index);
// };
// })(i);
// }
for (let i = 0; i < aBtn.length; i++) {
aBtn[i].onclick = function () {
console.log(i);
};
}
</script>
</html>
<!DOCTYPE html>
<html>
<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>@说人话的前端 - bilibili</title>
</head>
<body></body>
<script>
// 隐藏变量
function fn() {
const data = {};
return {
set: function (key, val) {
data[key] = val;
},
get: function (val) {
return data[val];
},
};
}
const json = fn();
json.set("age", 18);
console.log(json.get("age"));
</script>
</html>
请描述event loop的机制
Javascr是如何执行的?
- 自上而下,从左到右一行一行执行
- 如果有一行报错,后面的代码不执行
- 先执行同步代码,再执行异步代码(setTimeout、Ajax
Event Loop 过程
- 同步代码,一行一行放在 Call Stack 中执行
- 遇到异步,会先“记录”下代码,等待执行时机(setTimeout、Ajax)。时机到了,将之前“记录”的代码放入 Callback Queue
- 当 Call Stack 为空(同步代码执行完),Event Loop 开始工作
- Event Loop 轮询查找 Callback Queue 中是否有可执行的代码。如果有,将代码移动到 Call Stack 中执行
- Event Loop 如果没有找到可以执行代码,则会继续轮询查找
.offsetWidth;
console.log(w);
</script>
</body>
</html>