闭包高级、对象、构造函数、实例化
闭包高级
函数被定义时生成[[scope]]->生成scope chain -> scope chain中存着上级的环境。
函数被执行的前一刻(预编译过程),生成自己的AO,排到scope chain的最顶端。
函数执行完毕的两种情况:
- 一般情况:函数执行完毕,函数的scope chain与自身AO连线中断,函数的AO也被销毁。
- 闭包现象:函数执行完毕,函数的scope chain与自身AO连线中断,但函数的AO没有被销毁,在内部函数的scope chain上存在。
再说一遍闭包的定义:
内部函数被返回到外部并保存时,一定会产生闭包现象,使原来的作用域链不释放(只要程序整个不被销毁,原来的作用域链就永不释放),从而可以对函数内部变量进行访问和更改。
闭包用途
- 封装插件
- 模块化编程
对象
创建对象的两种方法
-
对象字面量
var obj; obj = { name: 'white', sex: 'man', paly: function(){ //对象中属性值为函数的属性叫做方法 } }
-
构造函数实例化
- 系统自带的构造函数
new Object()
,与对象字面量相等。 - 自定义构造函数(构造工厂)
- 系统自带的构造函数
增、删、改、查对象的属性/方法
- 通过.点语法:
- 访问(查)
- 改变(改变)
- 增加(增)
- 通过关键字
delete
来删除对象属性/方法。
在对象内部也可以操作对象的属性:
var teacher = {
name: 'white',
height: '178',
weight: '80',
sports: function(){
teacher.weight--;
console.log(teacher.weight);
}
}
teacher.sports(); //79
在对象内部使用对象名.属性
来访问对象自己的属性很别扭,怎么办?
->使用this,对象中this代表对象本身。
var teacher = {
name: 'white',
height: '178',
weight: '80',
sports: function(){
this.weight--;
console.log(this.weight);
}
}
teacher.sports(); //79
构造函数
定义
构造函数仍然是函数,在命名上我们习惯使用大驼峰命名。
我的理解:构造函数是为了创建对象而存在的,于是它的内部都是this.属性名=属性值
function Teacher(){
this.name = 'white';
this.sex = 'man';
this.weight = 80
this.sports = function(){
this.weight--;
console.log(this.weight);
}
}
请问:这里的this指向谁?
答:函数不执行,this不存在。想要this存在,必须实例化,谁用this就指向谁。
对象可以由构造函数实例化而创建,而this是指向对象本身的。
实例化
怎么实例化:new
关键字
var teacher1 = new Teacher();
teacher1.sports(); //构造函数内部也可以操作对象的属性
console.log(teacher1);
构造函数实例化对象的好处:
通过一个构造函数创建的多个对象,为不同的对象,相互之间不影响。
对于上述的构造函数有一个问题:创建出的对象虽然不同,但大家的属性都相同;现在我们想要创建的对象彼此的属性值不同,有什么办法?
传参
-
传值
function Teacher(name, course, sex){ this.name = name; this.course = course; this.sex = sex; } var teacher1 = new Teacher('white', 'Math', 'man'); var teacher2 = new Teacher('black', 'Chinese', 'woman'); console.log(teacher1); //Teacher {name: 'white', course: 'Math', sex: 'man'} console.log(teacher2); //Teacher {name: 'black', course: 'Chinese', sex: 'woman'}
-
传对象
function Teacher(opt){ this.name = opt.name; this.course = opt.course; this.sex = opt.sex; } var teacher = new Teacher({ name: '沈剑心', course: 'Chines', sex: 'woman' }) console.log(teacher); //Teacher {name: '沈剑心', course: 'Chines', sex: 'woman'}
基本上使用构造函数实例化时,我们都使用传对象的形式实例化对象。
这里传的对象,实际上就是我们所说的配置项,维护方便,使用方便,且配置项可以随便调换顺序。例如:
Vue.js
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
其实框架就是写了一个超级复杂的构造函数,我们去实例化构造函数,并初始化然后去使用。
补充两个数组方法
indexOf()
方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
splice()
方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。