闭包
1.如何产生闭包
当一个嵌套的内部函数引用嵌套的外部函数的变量时,就产生了闭包
2.闭包到底是什么
函数 A 返回了一个函数 B,并且函数 B 中使用了函数 A 的变量,函数 B 就被称为闭包
循环遍历加监听
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button>点一下</button>
<button>点一下</button>
<button>点一下</button>
</body>
<script type="text/javascript">
var btns=document.getElementsByTagName('button');
for (var i = 0,length=btns.length; i < length; i++) {
(function (i) {
var btn=btns[i]
btn.onclick=function(){
alert("第"+(i+1)+"个");
}
})(i)
}
/*for (var i = 0,length=btns.length; i < length; i++) {
var btn=btns[i]
btn.index=i;
btn.οnclick=function(){
alert("第"+(this.index+1)+"个");
}
}*/
</script>
</html>
toUpperCase 和 toLowerCase
function myModule(){
var msg='My atguigu'
function doSomething(){
console.log('doSomething() '+msg.toUpperCase())//全部大写
}
function doOtherthing(){
console.log('doOtherthing() '+msg.toLowerCase())//全部小写
}
return {
doSomething: doSomething,
doOtherthing: doOtherthing
}
}
向外暴露对象
(function(){
var msg='My atguigu'
function doSomething(){
console.log('doSomething() '+msg.toUpperCase())
}
function doOtherthing(){
console.log('doOtherthing() '+msg.toLowerCase())
}
//向外暴露对象(给外部使用的方法)
window.myModule2={
doSomething: doSomething,
doOtherthing: doOtherthing
}
})()
闭包的应用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 将所有的数据功能都包装在一个函数内部
只向外暴露一个包含n个方法的对象或函数
模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能
-->
</body>
<!-- <script type="text/javascript" src="myModule.js"></script>
<script type="text/javascript">
var module=myModule()
module.doSomething()
module.doOtherthing()
</script> -->
<script type="text/javascript" src="myModule2.js"></script>
<script type="text/javascript">
myModule2.doOtherthing()
myModule2.doSomething()
</script>
</html>
JavaScript分线程
原:
//文件名 Web workers.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<input type="text" id="number">
<button id="btn">计算</button>
</body>
<script type="text/javascript">
function fibonacci(n){
return n<=2 ? 1:fibonacci(n-1)+fibonacci(n-2)
}
var input = document.getElementById('number')
document.getElementById('btn').onclick=function(){
var number=input.value
var result=fibonacci(number)
alert(result)
}
</script>
</html>
改:
//文件名 Web workers2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<input type="text" id="number">
<button id="btn">计算</button>
</body>
<script type="text/javascript">
var input = document.getElementById('number')
document.getElementById('btn').onclick=function(){
var number=input.value
var worker=new Worker('worker.js')
worker.onmessage=function(event){
console.log("分线程接收分线程发送的数据:"+event.data)
alert(event.data)
}
worker.postMessage(number)
console.log("主线程接收分线程发送的数据:"+number)
}
</script>
</html>
//文件名: worker.js
function fibonacci(n){
return n<=2 ? 1:fibonacci(n-1)+fibonacci(n-2)
}
var onmessage=function(event){
var number=event.data
console.log("分线程接收到主线程发送的数据:"+number)
var result=fibonacci(number)
postMessage(result)
console.log("分线程向主线程返回数据:"+result)
}
JS面向对象中继承的实现(ES5和ES6)
//ES5:寄生组合式继承:通过借用构造函数来继承属性和原型链来实现子继承父。
function Animal(name) {
this.name = name || 'Animal';
this.sleep = function () {
console.log('(Animal sleep) -> ' + this.name);
}
}
Animal.prototype.eat = function (food) {
console.log('(Animal eat) -> ' + food + ' -> ' + this.name);
}
function Cat(name) {
Animal.call(this);
this.name = name || 'Cat';
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Cat.prototype.eatFish = function (num) {
num = num || 'a little';
console.log('(Cat eatFish) -> ' + this.name + ' -> ' + num);
};
// Object.create()的polyfill
/*
function pureObject(o){
//定义了一个临时构造函数
function F() {}
//将这个临时构造函数的原型指向了传入进来的对象。
F.prototype = obj;
//返回这个构造函数的一个实例。该实例拥有obj的所有属性和方法。
//因为该实例的原型是obj对象。
return new F();
}
*/
let animal = new Animal('Dog');
console.log(animal.name); //Dog
animal.sleep(); //(Animal sleep) -> Dog
animal.eat('Meat'); //(Animal eat) -> Meat -> Dog
console.log('-----------'); //-----------
let cat = new Cat('Big Cat');
console.log(cat.name); //Big Cat
cat.sleep(); //(Animal sleep) -> Big Cat
cat.eat('Small Fish'); //(Animal eat) -> Small Fish -> Big Cat
cat.eatFish('more'); //(Cat eatFish) -> Big Cat -> more
// ES6
class Animal {
constructor(name) {
this.name = name || 'Animal';
this.sleep = function () {
console.log('(Animal sleep) -> ' + this.name);
}
}
eat(food) {
console.log('(Animal eat) -> ' + food + ' -> ' + this.name);
}
}
class Cat extends Animal {
constructor(name) {
super(name || 'Cat');
}
eatFish(num) {
num = num || 'a little';
console.log('(Cat eatFish) -> ' + this.name + ' -> ' + num);
}
//重新声明父类同名方法会覆盖,ES5直接在原型链上操作
eat(food) {
console.log('(重写的)(Animal eat) -> ' + food + ' -> ' + this.name);
}
}
let animal = new Animal('Dog');
console.log(animal.name); //Dog
animal.sleep(); //(Animal sleep) -> Dog
animal.eat('Meat'); //(Animal eat) -> Meat -> Dog
console.log('-----------'); //-----------
let cat = new Cat('Big Cat');
console.log(cat.name); //Big Cat
cat.sleep(); //(Animal sleep) -> Big Cat
cat.eat('Small Fish'); //(重写的)(Animal eat) -> Small Fish -> Big Cat
cat.eatFish('more'); //(Cat eatFish) -> Big Cat -> more
JS Array对象
var arr1 = [1, 2, 3, 41, 4, 3, 312, 3, 123];
console.log(arr1.constructor);
console.dir(arr1.constructor);
// Array对象方法
// join() 用于把数组中的所有元素放入一个字符串。
var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
console.log(arr.join(".")); //George.John.Thomas
//pop() 删除并返回数组的最后一个元素
console.log(arr1.pop()); //123
//shift() 删除并返回数组的第一个元素
// push() 向数组的末尾添加一个或更多元素,并返回新的长度。
var arrPush = ['first', 'second'];
console.log(arrPush.push('third', 'fourth'));
console.log(arrPush); //(4) ["first", "second", "third", "fourth"]
// unshift() 向数组的开头添加一个或更多元素,并返回新的长度。
// reverse() 颠倒数组中元素的顺序
console.log(arrPush.reverse()); //(4) ["fourth", "third", "second", "first"]
// splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目
// arrayObject.splice(index,howmany,item1,.....,itemX)
// index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
// howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
// item1, ..., itemX 可选。向数组添加的新项目。
// toSource() 返回该对象的源代码。
// 只有 Gecko 核心的浏览器(比如 Firefox)支持该方法,也就是说 IE、Safari、Chrome、Opera 等浏览器均不支持该方法。
function employee(name, job, born) {
this.name = name;
this.job = job;
this.born = born;
}
var bill = new employee("Bill Gates", "Engineer", 1985);
console.log(bill.toSource());
// toString() 把数组转换为字符串,并返回结果。
// toLocaleString() 把数组转换为本地数组,并返回结果。
// valueOf() 返回数组对象的原始值