1.单线程
(1)线程和进程
进程是 cpu 资源分配的最小单位(是能拥有资源和独立运行的最小单位)
线程是 cpu 调度的最小单位(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)
单线程与多线程,都是指在一个进程内的单和多。(所以核心还是得属于一个进程才行)
(2)浏览器是多进程 ,JavaScript是单线程的
总结一句话:如果没有遇到条件或者循环,程序按照顺序从上往下依次执行
(3)定时器
window.setTimeout(code,millisec);//等待一段时间(millisec)后执行一次函数内容,只执行一次
window.setInterval(code,millisec);//每隔一段时间(millisec)执行一次函数内容
window.可以省略
清除定时器
clearTimeout(定时器的ID)
clearInterval(定时器的ID)
(4)同步异步
同步任务(从上到下,依次执行)
异步任务(暂时挂起,先运行排在后面的任务)
异步编程主要有:1、setTimeout 2、ajax回调函数 3、promise对象 4、generator函数 5、事件机制
2.预解析(将以关键字var和function开头的语句块提前进行处理)
当变量和函数的声明处在作用域比较靠后的位置的时候,变量和函数的声明会被提升到作用域的开头,赋值不会被提升。
(1)函数提升(表达式声明的函数不会被提升)
func();
function func(){
alert("Funciton has been called");
}
由于JavaScript的预解析机制,上面的代码就等效于:
function func(){
alert("Funciton has been called");
}
func()
(2)变量提升
alert(a);
var a = 1;
上面的代码就等效于
var a; //这里是声明
alert(a); //变量声明之后并未有初始化和赋值操作,所以这里是 undefined
a = 1
(3)函数同名,后覆盖前
func1();
function func1(){
console.log('This is func1');
}
func1();
function func1(){
console.log('This is last func1');
}
输出结果为
This is last func1
This is last func1
原因分析:由于预解析机制,func1的声明会被提升,提升之后的代码为
function func1(){
console.log('This is last func1');
}
func1();
func1();
用function声明的函数:同名的函数,后面的会覆盖前面的
函数表达式声明的函数:不会覆盖,采用就近原则。
(4)变量和函数同名(变量会被忽略,或变量覆盖函数——看顺序)
alert(foo);
function foo(){}
var foo = 2;
当出现变量声明和函数同名的时候,只会对函数声明进行提升,变量会被忽略。所以上面的代码的输出结果为
function foo(){}
预解析之后的代码:
function foo(){};
alert(foo);
foo = 2;
第二种:
var num = 1;
function num () {
alert( num );
}
num();
代码执行结果为:
Uncaught TypeError: num is not a function
按照常规的书写顺序,同名的函数与变量,变量会覆盖函数
预解析后的代码:
function num(){
alert(num);
}
var num = 1;
num();
(5)预解析是分作用域的(局部可以用全局变量,全局不能用局部变量)
3.作用域
(1)全局作用域
在全局作用域中有一个全局对象 window(代表的是一个浏览器的窗口,由浏览器创建),可以直接使用。
所有创建的变量都会作为 window 对象的属性保存。
(2)局部作用域(函数作用域)
在函数内部就是局部作用域,这个代码的名字只在函数的内部起作用
调用函数时创建函数作用域,函数执行完毕之后,函数作用域销毁;
每调用一次函数就会创建一个新的函数作用域,它们之间是相互独立的。
(3)隐式全局变量
声明变量使用`var`, 如果不使用`var`声明的变量就是全局变量( 禁用 )
(4)作用域及作用域链
全局作用域---全局变量
局部作用域---局部变量---只在当前作用域下有效
块作用域?(ES5中没有,ES6中存在)
只有函数才能产生局部作用域
作用域链的查找规则:
先从当前的作用域中查找,如果有,就返回
如果没有从上一级查找,有就返回,没有继续上一级查找,直到全局
如果全局没有,就报错
4.对象
(1)对象的创建方式
1.对象字面量
var obj1 = { name: "zs", sex: "男", age: 20 }
2.内置构造函数new Object()创建对象
var person = new Object();
person.name = 'lisi';
person.age = 35;
3.工厂函数创建对象
function createPerson(name, age, job) {
var person = new Object(); //创建对象
person.name = name;
person.age = age;
person.job = job;
person.sayHi = function(){ //函数,对象行为
console.log('Hello,everyBody');
}
return person; //返回对象
}
var p1 = createPerson('张三', 22, 'actor');
4.自定义构造函数(要求名称首字母大写(规范))
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayHi = function(){ //行为,创建函数
console.log('Hello,everyBody');
}
}
var p1 = new Person('张三', 22, 'actor');
(2)new关键字——用来在创建对象时初始化对象
1.构造函数用于创建一类对象,首字母要大写。
2.构造函数要和new一起使用才有意义。
new在执行时会做三件事情:
1.new会在内存中创建一个新的空对象
var person = new Object(); //创建对象
2.new会让this指向这个新的对象
3.new会返回这个新对象
(3)this详解
函数内部的this几个特点:
1. 函数在定义的时候this是不确定的,只有在调用的时候才可以确定
2. 一般函数直接执行,内部this指向全局window
3. 函数作为一个对象的方法,被该对象所调用,那么this指向的是该对象
4. 构造函数中的this其实是一个隐式对象,类似一个初始化的模型,所有方法和属性都挂载到了这个隐式对象身上,后续通过new关键字来调用,从而实现实例化
(4)对象的使用
1. 取出对象属性对应的属性值有两种方法
方法一:obj.name——(对象.属性)
方法二:用[ ](数组的方式)
obj1[‘name’]——(对象[‘属性’])
2.遍历对象的属性
通过for..in语法可以遍历一个对象
对象的key(属性名)不会重复,如果有,后面会覆盖前面
也可以 for(value in obj1){ }
3.利用对象key(属性名)不重复的特性进行数组去重
过程:1.遍历数组,把数组的每一项当作对象的属性名
2.取出所有的属性名,加入到新数组
数组为字符串类型
数组为数字类型
将arr2.push(key)——>arr2.push(Number(key))
4.删除对象的属性(delete)
delete obj.name;
5.JavaScript错误(了解)
(1)JavaScript try(尝试运行) 和 catch(捕获异常)
try 和 catch 是成对出现
var txt="";
function message() {
try { adddlert("Welcome guest!"); }
catch(err) { txt="本页有一个错误。\n\n";
txt+="错误描述:" + err.message + "\n\n";
txt+="点击确定继续。\n\n";
alert(txt);
} }
(2) finally语句
finally 语句不论之前的 try 和 catch 中是否产生异常都会执行该代码块。
finally { document.getElementById("demo").value = ""; } }
(3)throw语句——创建或抛出异常
语法:throw exception
function myFunction() { var message, x; message = document.getElementById("message"); message.innerHTML = ""; x = document.getElementById("demo").value; try { if(x == "") throw "值为空"; if(isNaN(x)) throw "不是数字"; x = Number(x); if(x < 5) throw "太小"; if(x > 10) throw "太大"; } catch(err) { message.innerHTML = "错误: " + err; } }