1、JavaScript基础数据类型
包括原始类型和引用类型
原始类型有5个:
Number(数值) String(字符串) Boolean(布尔) Null(空) Undefined(未定义)
引用类型有1个:
Object(对象)
通过typeof(x)可以返回一个变量x的数据类型;
注意一点:typeof运算符对于null类型返回的是object。
2、JavaScript作用域链
当执行一段JavaScript代码(全局代码或函数)时,JavaScript引擎会创建为其创建一个作用域又称为执行上下文(Execution Context),在页面加载后会首先创建一个全局的作用域,然后每执行一个函数,会建立一个对应的作用域,从而形成了一条作用域链。每个作用域都有一条对应的作用域链,链头是全局作用域,链尾是当前函数作用域。
作用域链的作用是用于解析标识符,当函数被创建时(不是执行),会将this、arguments、命名参数和该函数中的所有局部变量添加到该当前作用域中,当JavaScript需要查找变量X的时候(这个过程称为变量解析),它首先会从作用域链中的链尾也就是当前作用域进行查找是否有X属性,如果没有找到就顺着作用域链继续查找,直到查找到链头,也就是全局作用域链,仍未找到该变量的话,就认为这段代码的作用域链上不存在x变量,并抛出一个引用错误(ReferenceError)的异常。
3、JavaScript原型链
JavaScript中的每个对象都有一个prototype属性,我们称之为原型,而原型的值也是一个对象,因此它也有自己的原型,这样就串联起来了一条原型链,原型链的链头是object,它的prototype比较特殊,值为null。
原型链的作用是用于对象继承,函数A的原型属性(prototype property)是一个对象,当这个函数被用作构造函数来创建实例时,该函数的原型属性将被作为原型赋值给所有对象实例,比如我们新建一个数组,数组的方法便从数组的原型上继承而来。
当访问对象的一个属性时, 首先查找对象本身, 找到则返回; 若未找到, 则继续查找其原型对象的属性(如果还找不到实际上还会沿着原型链向上查找, 直至到根). 只要没有被覆盖的话, 对象原型的属性就能在所有的实例中找到,若整个原型链未找到则返回undefined;
4、new构建对象的本质
function User(){
this.name = "jay";
this.age = 23;
}
var user = new User();
通过new操作符,实际上在构造函数User中完成了如下操作:
• 创建一个新的对象,这个对象的类型是object;
• 设置这个新的对象的内部、可访问性和prototype属性为构造函数(指prototype.construtor所指向的构造函数)中设置的;
• 执行构造函数;
• 返回新创建的对象。
function User(){
//this = {};
//this.constructor = User;
this.name = "Vicfeel";
this.age = 23;
//return this;
}
var user = new User();
如果构造函数默认返回的新创建的this对象,如果手动return 一个变量的话,如果该变量是原始类型则无效,如果是对象,则返回该对象。
5、JavaScript代理
当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数。
比如我们需要向一个ul中动态添加很多个li,需要遍历li逐个添加点击事件:
'list'>
var count = 100;
var ulList = document.getElementById("list");
//动态构建节点
for(var i = count;i--;){
var liDom = document.createElement('li');
ulList.appendChild(liDom);
}
//绑定点击事件
var liNode = ulList.getElementByTagName("li");
for(var i=0, l = liNodes.length; i < l; i++){
liNode[i].onClick = function(){
//li点击事件
}
}
DOM操作是十分消耗性能的。所以重复的事件绑定简直是性能杀手。
而事件代理的核心思想,就是通过尽量少的绑定,去监听尽量多的事件;
利用事件冒泡机制,对其父节点ul进行事件绑定(Event Bubble),然后通过event.target来判断是哪个节点触发的事件,从而减少很多EventHandler的绑定。
var count = 100;
var ulList = document.getElementById("list");
//动态构建节点
for(var i = count;i--;){
var liDom = document.createElement('li');
ulList.appendChild(liDom);
}
//绑定点击事件
var liNode = ulList.getElementByTagName("li");
liNode.onClick = function(e){
if(e.target && e.target.nodeName.toUpperCase == "li") {
// li点击事件
}
}
事件冒泡
事件冒泡:JavaScript允许DOM元素嵌套在一起。在这种情况下,如果单击子级的处理程序,父级的处理程序也将执行同样的工作。
阻止事件冒泡的两种方法:
方法一:event.stopPropagation( );
这是阻止事件的冒泡方法,不让事件向documen上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接仍然会被打开,
在ie浏览器中阻止冒泡的方法是window.event.cancelBubble=true而在谷歌,火狐等浏览器的方法则是e.stopPropagation()
方法二:event.target
获取到触发事件的元素
6、JavaScript中定时器如何工作、定时器的缺点
定时器用于在设定的时间执行一段代码,或者在给定的时间间隔内重复该代码。
通过使用函数setTimeout
,setInterval
和clearInterval
来完成。
setTimeout(function,delay)
函数用于启动在所述延迟之后调用特定功能的定时器。
setInterval(function,delay)
函数用于在提到的延迟中重复执行给定的功能,只有在取消时才停止。
clearInterval(id)
函数指示定时器停止。
缺点:定时器在一个线程内运行,因此事件可能需要排队等待执行。
7、 使用JavaScript提交表单
document.form [0] .submit();
8、JavaScript中的循环结构都有什么
For
、While
、do-while
、 loops
9、Void(0)怎么用
Void(0)用于防止页面刷新,并在调用时传递参数“zero”。
Void(0)用于调用另一种方法而不刷新页面。
10、.call()和.apply()之间有什么区别?
.call()和.apply()之间的基本区别在于将参数传递给函数。
当程序员知道函数参数的编号时,使用.call(),因为它们必须在调用语句中被提及为参数。另一方面,当不知道数字时使用.apply(),函数.apply()期望参数为数组。
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//输出:
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2
new Foo().getName();//3
new new Foo().getName();//3