call()
方法调用一个函数,其具有一个指定的 this
值和分别地提供的参数(参数的列表)
注意:该方法的作用和 apply()
方法类似,只有一个区别,就是call()
方法接收的是若干个参数的列表,而apply()
方法接收的是一个包含多个参数的数组。
语法:
fun.call(thisArg,arg1,arg2)
参数:
thisArg
arg1,arg2,...
<script>
var obj = {
name: "admin",
};
function foo(a, b) {
console.log(this.name); // admin this指向obj
console.log(a + b); // 30
}
foo.call(obj, 10, 20);
script>
apply()
方法调用一个函数,其具有一个指定的this
值,以及作为一个数组(或类似数组的对象)提供的参数
注意:该方法的作用和call()
方法类似,只有一个区别,就是call()
方法接受的是若干个参数的列表,而apply()
方法接收的是一个包含多个参数的数组。
语法:
fun.apply(thisArg,[argsArray])
参数:
thisArg
argsArray
apply()
与call()
非常相似,不同之处在于提供参数的方式
apply()
使用参数数组而不是一组参数列表
fun.apply(this,['eat','bananas'])
<script>
var obj = {
name: "admin",
};
function foo(a, b) {
console.log(this.name); // admin this指向obj
console.log(a + b); // 30
}
foo.apply(obj, [10, 20]);
script>
bind()
函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体。
当目标函数被调用时 this
值绑定到bind()
的第一个参数,该函数不能被重写。绑定函数被调用时,bind()
也接收预设的参数提供给原函数
一个绑定函数也能使用 new 操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数
语法:
fun.bind(thisArg,arg1,arg2,...)
参数:
thisArg
arg1,arg2,...
<script>
var obj = {
name: "admin",
};
function foo(a, b, c, d) {
console.log(this.name); // admin this指向obj
console.log(a + b); // 30
console.log(c + d); // 70
}
// foo.bind(obj, 10, 20)(); // 最后一个括号表示调用
foo.bind(obj, 10, 20)(30, 40);
script>
call()
和apply()
特性一样
this
的指向null
或者undefined
,则内部 this 指向 windowbind
call
、apply
最大的区别是:bind
不会调用bind
支持传递参数,它的传参方式比较特殊,一共有两个位置可以传递
bind
的同时,以参数列表的形式进行传递bind
的时候以传递的参数为准还是以调用的时候传递的参数为准
bind
的时候传递的参数和调用的时候传递的参数会合并到一起。传递到函数内部js 的加载、解析和执行会阻塞页面的渲染过程,因此我们希望 js 脚本能够尽可能的延迟加载,提高页面的渲染速度。
JS 延迟加载的方式:
将 js 脚本放在文档底部,来使 js 脚本尽可能的在最后来执行
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>Documenttitle>
head>
<body>body>
<script src="./js1.js">script>
html>
给 js 脚本添加 defer 属性,这个属性会让脚本的加载与文档的解析同步,然后在文档解析完成后再执行这个脚本文件,这样的话就能使页面的渲染不被阻塞。多个设置了 defer 属性的脚本按规范来说最后是顺序执行的,但是在一些浏览器中可能不是这样的
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>Documenttitle>
<script src="./js1.js" defer>script>
head>
<body>body>
html>
给 js 脚本添加 async 属性,这个属性会使脚本异步加载,不会阻塞页面的解析过程,但是当脚本加载完成后立即执行 js 脚本,这个时候如果文档没有解析完成的话同样会阻塞。多个 async 属性的脚本的执行顺序是不可预测的,一般不会按照代码的顺序依次执行
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>Documenttitle>
<script src="./js1.js" async>script>
head>
<body>body>
html>
动态创建 DOM 标签的方式,我们可以对文档的加载事件进行监听,当文档加载完成后再动态的创建 script 标签来引入 js 脚本
<script type="text/javascript">
function downloadJS() {
var element = document.createElement("script");
element.src = "test.js";
document.body.appendChild(element);
}
//三种事件模型,DOM0,DOM2,IE
if (window.addEventListener) {
window.addEventListener("load", downloadJS, false);
} else if (window.attachEvent) {
window.attachEvent("onload", downloadJS);
} else {
window.onload = downloadJS;
}
script>
box-sizing
有几种,都有什么区别?W3C 盒子模型(content-box
)
box-width = width + 2 * padding + 2 * border
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>Documenttitle>
<style>
div {
box-sizing: content-box;
width: 100px;
height: 100px;
padding: 1px;
border: 1px solid yellow;
background: red;
}
style>
head>
<body>
<div>div>
body>
html>
IE 盒子模型(border-box
)
box-width = width
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>Documenttitle>
<style>
div {
box-sizing: border-box;
width: 100px;
height: 100px;
padding: 1px;
border: 1px solid yellow;
background: red;
}
style>
head>
<body>
<div>div>
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>Documenttitle>
<style>
.red {
color: red;
}
.green {
color: green;
}
style>
head>
<body>
<div class="red green">第一行:颜色是什么?div>
<div class="green red">第二行:颜色是什么?div>
body>
html>
函数防抖:是指在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。这可以使用在一些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求
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>Documenttitle>
head>
<body>
<input type="text" />
body>
<script>
// 防抖:用户触发事件过于频繁,只要最后一个事件的操作
let input = document.querySelector("input");
// let t = null;
// input.onchange = function () {
// if (t !== null) {
// clearTimeout(t);
// }
// t = setTimeout(() => {
// console.log(this.value);
// }, 500);
// };
// 根据上面的代码做出封装 使代码逻辑便于维护
input.onchange = debounce(function () {
console.log(this.value);
}, 500);
// 利用闭包
function debounce(fn, delay) {
let t = null;
return function () {
if (t !== null) {
clearTimeout(t);
}
t = setTimeout(() => {
fn.call(this);
}, delay);
};
}
script>
html>
函数节流:是指规定一个单位事件,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。
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>Documenttitle>
<style>
body {
height: 2000px;
}
style>
head>
<body>body>
<script>
// 防抖:只执行最后一次
// 节流:控制执行次数 作用:控制高频时间执行次数
// let flag = true;
// window.onscroll = function () {
// if (flag) {
// setTimeout(() => {
// console.log("hello world");
// flag = true;
// }, 500);
// flag = false;
// }
// };
window.onscroll = throttle(function () {
console.log("hello world");
}, 500);
function throttle(fn, delay) {
let flag = true;
return function () {
if (flag) {
setTimeout(() => {
fn.call(this);
flag = true;
}, delay);
flag = false;
}
};
}
script>
html>
区别:两者区别在于函数节流是固定时间做某一件事,比如每隔 1 秒发一次请求。而函数防抖是频繁触发后,只执行一次(两者的前提都是频繁触发)
console.log
打印顺序的判断 <script>
setTimeout(function () {
console.log("1");
}, 0);
new Promise(function (resolve) {
console.log("2");
resolve();
}).then(function () {
console.log("3");
});
console.log("4");
// 2 4 3 1
// 打印顺序: Promise log Promise其后的.then() setTimeout
script>