JavaScript语言是单线程的
1、定时器
window对象提供了两个方法来实现定时器的效果,分别是window.setTimeout()和window.setInterval。其中前者可以使一段代码在指定时间后运行;而后者则可以使一段代码每过指定时间就运行一次。
window.setTimeout(code,millisec);
window.setInterval(code,millisec);
其中,code可以是用引号括起来的一段代码,也可以是一个函数名,到了指定的时间,系统便会自动调用该函数,当使用函数名作为调用句柄时,不能带有任何参数;而使用字符串时,则可以在其中写入要传递的参数。两个方法中的第二个参数是millisec,表示延时或者重复执行的毫秒数。
清除定时器
clearTimeout(定时器名)
clearInterval(定时器名)
var num = 10
// var testTime = setInterval(function time() {
// num--
// console.log(num + "s后重试");
// document.write(num + "s" + " ")
// if (num == 0) {
// clearInterval(testTime)
// }
// }, 100);
// // console.log(testTime);
// function name() {
// alert("哈哈哈哈")
// }
// name()
// var testTime1=setTimeout(function time1() {
// console.log("一次计时器");
// },6000)
2、预解析
(1)、函数提升
func();
function func(){
alert("Funciton has been called");
}//函数声明
由于JavaScript的预解析机制,上面的代码就等效于:
function func(){
alert("Funciton has been called");
}
func()
(2)、变量提升
看完函数声明的提升,再来看一个变量声明提升的例子
alert(a);
var a = 1;
由于JavaScript的预解析机制,上面这段代码,alert出来的值是undefined,如果没有预解析,代码应该会直接报错a is not defined,而不是输出值,不是说要提前的吗?那不是应该alert出来1,为什么是undefined?
所以我们说的提升,是声明的提升。
那么再回过头看,上面的代码就等效于
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();
同名的函数,后面的会覆盖前面的,所以两次输出结果都是This is last func1。
(4)、变量和函数同名
alert(foo);
function foo(){}
var 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)、预解析是分作用域的
提升原则是提升到变量运行的环境(作用域)中去。
function showMsg()
{
var msg = 'This is message';
}
alert(msg); // msg未定义
还是直接把预解析之后的代码写出来:
function showMsg()
{
var msg;
msg = 'This is message';
}
alert(msg); // msg未定义
(6)、函数表达式不会提升
func();
var func = function(){
alert("我被提升了");
};
函数表达式,并不会被提升。只是简单地当做变量声明进行了处理
var func;
func();
func = function(){
alert("我被提升了");
}
3、作用域
全局作用域---全局变量
局部作用域---局部变量---只在当前作用域下有效
只有函数才能产生局部作用域
作用域链的查找规则:
先从当前的作用域中查找,如果有,就返回
如果没有从上一级查找,有就返回,没有继续上一级查找,直到全局
如果全局没有,就报错
代码如下:
function name() {//声明函数
s1=6//隐形全局变量
var s3=5//局部变量
return s3 //返回值
}//函数外如果调用函数内局部变量,必须将局部变量return
name()//调用函数
console.log(s1);//打印的值与函数无关,可打印s1,s3,但s3因为return不能打印
console.log(name());//对于打印调用函数的,输出的值只为return返回的值,为s3
4、对象
(1)、对象字面量
var o = {
name: 'zs',
age: 18,
sex: true,
sayHi: function () {
console.log(this.name);
}
};
(2)、内置构造函数new Object()创建对象
var person = new Object();
person.name = 'lisi';
person.age = 35;
person.job = 'actor';
person.sayHi = function(){
console.log('Hello,everyBody');
}
(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');
(5)、new的关键字
构造函数,是一种特殊的函数。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
1.、构造函数用于创建一类对象,首字母要大写。
2.、构造函数要和new一起使用才有意义。
new在执行时会做三件事情:
1、new会在内存中创建一个新的空对象
2、new会让this指向这个新的对象
3、new会返回这个新对象
(6)、this的详解
JS中this的指向问题,有时会让人难以捉摸,随着学习的深入,我们可以逐渐了解。
函数内部的this几个特点:
1. 函数在定义的时候this是不确定的,只有在调用的时候才可以确定
2. 一般函数直接执行,内部this指向全局window
3. 函数作为一个对象的方法,被该对象所调用,那么this指向的是该对象
4. 构造函数中的this其实是一个隐式对象,类似一个初始化的模型,所有方法和属性都挂载到了这个隐式对象身上,后续通过new关键字来调用,从而实现实例化
(7)、对象的使用
遍历对象的属性
通过for..in语法可以遍历一个对象
删除对象的属性
function fun() {
this.name = 'mm';
}
var obj = new fun();
console.log(obj.name); // mm
delete obj.name;
console.log(obj.name); // undefined