一.作用域和闭包
作用域:全局.函数.块
1.作用于全局的默认的不可删除
由全局对象调用的
全局对象如果在浏览器运行js,那么全局对象就是window
let user = {
name: 1
}
console.log(user)
//Object { name: 1 } name: 1
console.log(window.user)//undefined
2.函数作用域
在函数中定义的变量查询时会先在函数内部查询,有就会直接返回,如果没有则自动返回上一级查询再来返回全局的这个变量
上面的查询变量的过程,就是一个链式查询的一个过程,称为:作用域链
let user = 1
console.log(user)//1 } 1
console.log(window.user)//undefined
//let声明的对象不属于顶层属性
function getuser() {
//私有变量
let user1 =
2
//user是声明在函数外面的全局变量
//可以在函数内使用
return ` ${user}, ${user1};`
}
console.log(getuser());
// 1,2
3.块作用域
就是在一对大括号里面的就是块作用域
console.log(getuser());
{
let a = 1;
let b = 2;
console.log(a, b);//1,2
}
console.log(a, b );//not defined
4.闭包
闭包:能够访问自由变量的函数
形参,函数中带有的参数
自由变量,函数参数以外的变量
理论上讲,所有函数都是闭包
let c = 1;
function add(a, b) {
return a + b + c
}
//c变量的访问就是闭包add访问了自由变量c
console.log(add(2, 3)); //6
通过闭包访问私有变量
作用于控制权限
function add() {
let c = 3
return function add1() {
return c
}
}
let f = add()
console.log(f()); //3
console.log(add()());//3
二.循环
1.while:入口判断
let arr = [1, 2, 3];
console.log(arr);
// 循环变量的初始化
i = 0;
while (i < arr.length) {
console.log(arr[i]);
//要有条件更新不然会进入死循环
i++
}
2.do while出口判断
do {
i = 5
console.log(arr[i]);//undefined
i++ //记得条件更新
console.log(`被执行了一次`);//被执行一次
}
while (i < arr.length)
3.对象的遍历 for-in
const lesson = {
"my name": "javaScript编程"
, score: 100
}
for (let key in lesson) {
console.log(lesson[key]);
}
4.for循环
for(初始化;条件;更新条件)
// while的简化版
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
5.for-of
用于对数组的遍历,对象不能使用这个
for (let item of arr) {
console.log(arr);
}//Array(3) [ 1, 2, 3 ]
三.迭代器
一、迭代器的定义:
迭代器是一种特殊对象,,所有的迭代器对象都有一个next()方法,每次调用都返回一个结果对象。结果对象有两个属性:一个是value,表示下一个将要返回的值;另一个是done,它是一个布尔类型的值,当没有更多可返回数据时返回true。迭代器还会保存一个内部指针,用来指向当前集合中值的位置,每调用一次next()方法,都会返回下一个可用的值
如果在最后一个值返回后再调用next()方法,那么返回的对象中属性done的值为true,属性value则包含迭代器最终返回的值,这个返回值不是数据集的一部分,它与函数的返回值类似,是函数调用过程中最后一次给调用者传递信息的方法,如果没有相关数据则返回undefined
function myIterator(data) {
// 迭代器中必须要有一个next();
let i = 0;
return {
next() {
// done,表示遍历是否完成?
// value:当前正在遍历的数据
let done = i >= data.length;
//返回布尔值
let value = !done ? data[i++] : undefined;
return { done, value };
}
}
}
let iterator = myIterator(['html', 'css', 'js', 'php']);
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
四.构造函数和原型
常识:任何一个函数都是对象:有一个属性叫:prototype(原型属性)
函数有两个功能
基本功能是封闭操作步骤
扩展功能 :当成对象的构造器,构造函数,对象生成器来用
function User(name, email) {
// 1.内部会自动创建一个this,指向新生成的对象
this.name = name;
this.email = email;
}
const user2 = new User('admin', 'admin@163.com');
console.dir(user2);
// user对象的原型属性永远指向它的构造函数的原型属性对象
五.类的对象和继承
js中没有类的概念,都是通过原型实现继承的。
通过构造函数插件对象的工程,叫“类的实例化”
function User(name, email) {
this.name = name;
this.email = email;
this.show = function () {
return {
name: this.name,
email: this.email
}
}
}
//构造函数对象的原型对象上的成员,可以被所有实例共享
const user1 = new User(1, 2);
console.log(user1);
//Object { name: 1, email: 2, show: show() }
es6之后简化 类的调用
class user2 {
// 构造方法:初始化对象的
constructor(name, email) {
this.name = name;
this.email = email
}
show() {
// 非静态成员中的this表示的就是当前属性值
return this;//mame,email
}
static fetch() {
return this
// 静态成员中的this表示的就是当前的类 }
}
static userName = '1111';
}
const user3 = new user2(`111`, `1232131`)
console.log(user3);//Object { name: "111", email: "1232131" }
console.log(user3.show());//Object { name: "111", email: "1232131" }
//静态方法
console.log(user2.userName);//1111
console.log(user2.fetch());//class user2 { constructor(name, email) }
继承:扩展父类
class新类名 extends 父类
class Child extends User2 {
constructor(name, email, gender) {
// 第一步必须将父类的构造方法来重新执行],否则this用不了
super(name, email);
// 第二步:给子类的新成员去初始化
this.gender = gender;
}
//更新
show() {
return { name: this.name, email: this.email, gender: this.gender };
}
}
const child = new Child("111", "4645646", "男");
console.log(child.show());//111, "4645646, 男