- 形成一个闭包
函数里面返回一个函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>闭包</title>
<style>
li{
border: 1px solid red;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
// 为什么会有闭包,因为作用域的问题
// 自调用()(),
function a(){
return function b(){
// 一个函数里面放回一个函数这种情况称为闭包
console.log('这是访问闭包里的返回函数');
}
}
// 访问闭包的方法
a()();
// 闭包的用途,保存私有的方法和私有的数据
// 优点:浏览器默认会清理掉没有使用的变量,可以通过闭包的方式内部调用变量来实现储存的变量和方法
// 缺点:但是相应的会造成浏览器内存的占用,使得内容运行缓慢
function b(){
var b = 2;
return function c(){
var sum = b + 1;
console.log(sum);
}
}
b()();
// ()() 还有个用途就是生成一个 命名空间, 可以 类似于自调用,前面的括号放我们的闭包函数
// 后面的括号相当于调用这个闭包函数里面也可以传参数
// 事件队列:在大量事件待执行的时候会把事件列一个队列等待调用
var dom = document.querySelectorAll('li');
for(let j=0;j<dom.length;j++){
dom[j].onclick=function(){
console.log(j+1)
}
}
// 需求:根据点击打印出点击的下标
// let 是局部变量,而var 是全局变量,因此后者需要调用闭包来达到需求
for(var i =0;i<dom.length;i++){
dom[i].onclick=(
function(a){
return function(){
console.log(a+1)
}
}
)(i)
}
// 倘若不进行闭包处理,var的变量会执行完for循环,点击时i全变成了6
// 添加事件的扩展
// DOM 事件 最常用的
var lis = document.querySelectorAll('li')
for(let i=0;i<lis.length;i++){
// 参数;事件类型 事件处理函数(回调) 监听器 冒泡或者捕获(布尔值)
lis[i].addEventListener('click',function(){
console.log(i);
},false)
}
// 和onclick的区别,onclick会覆盖,也就是说只能同一个节点有一个
// 而addEventListener不会覆盖
// 伪数组 arguments 不能直接使用数组方法
// 但是可以通过call 和 apply 上下文方法来使用
Array.prototype.join.call('arguments',['-']);
// 在arguments数组里的属性之间加一个 -
</script>
</body>
</html>
- 继承
继承的几种方式
1.ES6 extends
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>继承</title>
</head>
<body>
<script>
// 继承实现的原理:通过原型链 实现的继承
// 抽象出共有的属性或者方法
// ES6
class People{
constructor(name,age,skin){
this.name = name,
this.age = age,
this.skin = skin
}
eat(){
console.log('吃饭')
}
sleep(){
console.log('睡觉')
}
speak(){
console.log('说话')
}
}
// 继承 extends
class Student extends People{
constructor(name,age,skin,id,classs){
super(name,age,skin)
this.id = id,
this.classs=classs
}
study(){
console.log('读书')
}
}
var ren = new Student('张三',14,'yellow',01,'学生')
// 控制台可见,eat方法在对象ren的原型 的原型里
console.log(ren.eat());
</script>
</body>
</html>
继承的几种方式
1.构造函数继承
构造函数通过call(this)继承另一个构造函数(无法继承方法或属性)
2.原型继承
new一个构造函数A等于另一个构造函数B的原型,然后通过new B生成一个继承对象(多对一,一个对象更改继承的函数数据就会更改)
3.组合继承
构造函数和原型函数一起使用,更改B的原型指向自己B
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>继承-2</title>
</head>
<body>
<script>
// 继承的几种方式
// 1.构造函数继承--------
/*
问题:
原型上的方法或者属性无法继承
*/
function Fn(){
this.name = '张三',
this.eat = function(){
console.log('eat');
}
}
function F(){
// call(obj,'') apply(abj,[]) 函数自带的方法 上下文 前面传参一样后面不一样
// 使用call和apply更改this指向
Fn.call(this)
// 这个时候的this相当于f,于是乎Fn里的this相当于替换成了f这样便达到了继承的效果
console.log(this); // f
}
var fn = new Fn();
console.log(fn);
var f = new F();
console.log(f);
// 2. 原型继承
// 问题: 公用一个原型对象,就会导致,一个修改了原型对象的值其余所有的都会被修改
function Fun(){
this.name = '张三',
this.color = ["1","2"]
this.eat = function(){
console.log('eat');
}
}
Fun.prototype.sleep=function(){
console.log('睡觉');
}
function X(){
}
X.prototype = new Fun();
var x = new X();
// 这个就可以继承Fun的原型上的方法
console.log(x);
var a = new X();
var b = new X();
a.color.push('李四');
console.log(b.color); // 更改a但是b的color也更改了
// 3.组合方式
function Fy(){
this.name = '张三',
this.color = ["1","2"]
this.eat = function(){
console.log('eat');
}
}
function Y(){
Fy.call(this)
}
// 把Fy原型赋给Y的原型
// Y.prototype = Fy.prototype
// Object.create创建一个对象,里面传一个对象
Y.prototype = Object.create(Fy.prototype);
// 更改Y原型的Y指向
Y.prototype.constructor = Y
var c = new Y();
var d = new Y();
c.color.push('5');
console.log(d.color)
// typeof 判断数据类型
// instanceof 判断前者是否在后者的原型对象里
console.log(c instanceof Y);
console.log(c instanceof Fy);
</script>
</body>
</html>
网友评论