JS面向对象:
面向对象的语言有三个特点:继承多态和封装
封装:看不到里边的东西,用好表面的功能
继承:子类会继承父类的一些方法和属性,子类又有自己的方法和属性
多重继承:继承多个父类的方法和属性。
什么是面向对象:使用对象时,只关注对象提供的功能,不关注其内部细节。比如JQuery(这是一种思想)比如Date getFullYear之类的方法,不了解内部功能,只需要了解怎样使用就行了。
对象:不了解内部结构,只知道表面的各种操作。
变量是自由的,属性是属于一个对象的。
作用域
var a=2
为一个变量分配内存,将其命名为a,然后将2这个值保存进变量,编译器会进行如下处理
1、遇到 var a ,编译器会询问
作用域是否已经有一个该名称的变量存在于
同一个作用域的
集合中。(一个查找变量是否声明过得过程,这个过程叫
域进行协助,查找方式有两种:LHS查询和RHS查询)如果是,编译器会忽略该声明,继续进行编译;否则它会要求作用域在当前作
用域的集合中声明一个新的变量,并命名为 a。
2、接下来
编译器会为引擎生成运行时所需的代码,这些代码被用来处理 a = 2 这个赋值
操作。引擎运行时会首先询问作用域,在
当前的作用域集合中
是否存在一个叫作 a 的
变量。如果是,引擎就会使用这个变量;如果否,引擎会继续查找该变量。
如果最后引擎找到了变量a,就会将2赋值给它,否则就会抛出一个异常。
总结:变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如 果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对 它赋值。
LHS和RHS
他们代表一个赋值操作的左侧和右侧,当变量出现在赋值操作的左边时,进行LHS查询:
LHS 查询则是试图 找到变量的容器本身,从而可以对其赋值,即赋值操作的目标是谁。右侧时进行RHS( retrieve his source value(取到它的源值))查询:
谁是赋值操作的源头。
Eg:
console.log(a);//这是一个RHS引用,因为a没有被赋值,所以需要查找并取得a的值(就是上边说的取到它的源值 )才能付给console.log()这个东西。
然而 var a=2就是一个LHS引用,因为我们想找到a这个变量的容器本身,就是说为=2这个赋值语句找到一个目标,这个目标也就是承载这条赋值语句的容器就是a。
再看一个复杂一点的eg:
function foo(a) {
console.log( a ); // 2
}
foo( 2 );
这里都进行了哪种类型的调用?
A:调用foo()这个函数是一个RHS调用,意味着浏览器要找到foo是什么?所以要先执行foo()这个函数类型的值,在调用这个函数时,要执行这个函数就相当于执行一个给a赋值的过程,这就是一个LHS引用。console。log()也进行了一次查询,找到给它赋值的源头是2,这是一个RHS引用
总结:作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。如果查找的目的是对 变量进行赋值,那么就会使用 LHS 查询;如果目的是获取变量的值,就会使用 RHS 查询。
1. 包含着整个全局作用域,其中只有一个标识符: foo 。
2。包含着 foo 所创建的作用域,其中有三个标识符: a 、 bar 和 b 。
3. 包含着 bar 所创建的作用域,其中只有一个标识符: c 。
作用域气泡
引擎会从最内部的作用域console。log()开始查找这个三个变量的引用,如果没找到a,那他就会到上级嵌套的foo这个函数的作用域气泡中去查找(这个作用域气泡不包括函数名,就是函数的内部内容)
作用域查找会在找到第一个匹配的标识符时停止
全局变量会自动成为全局对象,window.a(window就是一个全局对象,这里假如a是被其他同名变量遮蔽的全局变量,就可以通过这种方法被调用,但是非全局的变量被遮蔽了,是不论如何都无法被调用到的)
无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处 的位置决定
如上所述,词发作用域完全由函数的声明位置来定义,那么修改词法作用域是如何做到的呢?
两种机制:
一、eval()这个函数可以接受一个字符串作为参数
function foo(str, a) {
eval( str ); // 欺骗!
console.log( a, b );
}
var b = 2;
foo( "var b = 3;", 1 ); // 1, 3
eval()的执行遮盖了全局变量b,在foo函数内部新生成了一个b这个变量。
计时事件 setTimeout()和setInterval()的区别
这二者的使用方法都具有两个参数,第一个参数是调用的函数名,第二个参数是间隔的时间(以毫秒为单位)。
二者都是要求过一个指定的毫秒数后执行代码,二者的定义是setInterval() - 间隔指定的毫秒数不停地执行指定的代码。setTimeout() - 暂停指定的毫秒数后执行指定的代码,在实际使用中例如:setTimeout(“demo()”,5000),一旦调用了这个函数,每隔五秒钟就会执行一次demo这个函数,然而在执行函数的过程中,函数的主体部分可能还需要一部分时间去执行,也就是说,第一次函数调用到第二次函数调用的时间间隔是要超过5秒的,当对于事件的要求是每隔一段时间去调用一次函数,而函数的处理有需要很长的时间,这个时候就应该用setTimeout(),而如果使用setInterval(“demo()”,5000),就不会为自己所调用函数的时间所束缚,它的意义就在于每隔一段时间就重复执行一次demo函数。所以,如果要求每隔一个固定的精确的时间执行一次函数(比如页面内的时间显示)就应该用setInterval()这个函数对象。
当要停止setTimeout()这个函数是可以用clearTimeout()函数,停止setInterval()函数需要使用clearInterval()函数。