- js基本类型?
6种:number,object,function,undefined,boolean,string 另外es6增加了symbol
- ===与==
===(等同符):若===两边的数据类型相等,再比较两边的值;若两边的数据类型不相等,则直接返回false
==(等同符):若==两边的数据类型相等,则比较两边的值是否相等;若两边的数据类型不相等,则先将等号两边转换成相同类型,再进行比较。而转换有如下两条规则:
1.若等号两边出现string、number、boolean,则先将等号两边转换成number,再进行比较
2.若等号两边出现null和undefined,null和undefined只和自己相等,而NaN和谁都不相等,连自己也不相等
- null与undefined
- null表示无的对象,转换为数值时为0;undefined表示无的初始值,转换为数值时为NaN
- 当声明的变量还未被初始化时,变量的默认值为undefined;null用来表示尚未存在的对象,通常用来表示试图返回一个尚未存在的对象
- undefined用来表示缺少一个值,即此处应该有值但是却没有值
- null表示没有对象,即此处不该有值
- 如何检测Array
typeof方法可以检测number、string、boolean、undefined、object、function但是无法检测Array,另外需要注意的是,typeof方法返回的是字符串类型,即typeof(undefined)==“undefined”
检测数组的方法:
- instanceof: XX instanceof Array(返回true/false)
- constructor: XX.constructor==Array
- object.prototype.toSting.call(XX)==‘[object Array]’;
- Array.isArray(XX)(IE8之前不支持)
- 最佳写法!
var arr=[1,2,3];
function isArray(value){
if(type of Array.isArray=="function"){
return Array.isArray(value);
}else{
return Object.prototype.toString.call(value)=='[obiect Array]';}
}
- typeof和instanceof
typeof:javascript的类型判断函数,返回字符串格式
instanceof:判断构造函数原型
关于这个有篇文章写的挺好的深入理解javascript之typeof和instanceof
- js闭包
闭包:有权访问另一个函数作用域中的变量和函数,主要是为了设计私有的方法和变量
特性:函数嵌套函数;
函数的内部可以引用外部的参数和变量;
参数和变量不会被js垃圾回收机制回收;
好处:希望一个变量长期驻扎在内存中;
避免全局变量污染;
私有成员存在;
坏处:常驻内存,会增加内存使用量,使用不当容易导致内存泄漏
例子:
全局变量的叠加
var a=1;
function abc(){
a++;
alert(a);
}
abc();//2
abc();//3
那么局部变量如何累加呢?
function abc(){
var a=1;
return function(){//匿名函数
a++;
alert(a);}
}
var y=abc();//外部函数赋值变量y
y();//y函数调用一次,结果为2,相当于abc()
y();//y函数调用第二次,结果为3,实现累加
此处再放一个链接详解js闭包
- 原型模式
function Person(){}
Person.prototype.name="mike";
Person.prototype.age="13';
Person.prototype.sayName=function(){
alert(this.name);
}
var person1=new Person();
person1.sayName();//mike
var person2=new Person();
person2.sayName();//mike
构造函数是空函数,但是仍然可以通过调用构造函数来创建新对象,新对象有相同的属性和方法。
这就是使用原型对象的好处:所有的对象实例共享原型对象所包含的属性和方法。但也是它的一个缺点,包含引用类型值得属性,如数组,一旦一个实例的数组修改,所有实例的数组都将修改。
- js继承
- 原型链:利用原型让一个引用类型继承另一个引用类型的属性和方法
function parent(){
this.a="world";
this.b="world";
}//构造函数
parent.prototype={
a:"aaa";
b:"bbb";
c:"!";
}
function child(){
this.a="hello";
}
child.prototype=new parent();//不使用child原型,而是使用parent的实例创造出一个新的原型,child继承了parent对象的所有方法和属性
var child1=new child();1
console.log(child.a+""+child.b+""+child.c);//hello world!
2.借用构造函数:在子类型构造函数的内部调用超类型构造函数
function Parent(){
this.friends=['yve','jack','will'];
}
function Child(){
parent.call(this);
}
var kid1=new Child();
kid1.friends.push("nanshen");//['yve','jack','will','nanshen'];
var kid2=new Child();
console.log(kid2.friends);//['yve','jack','will'];
3.组合继承:将原型链和借用构造函数的技术组合在一起,使用原型链实现对原型属性和方法的继承,借用构造函数来实现对实例属性的继承。
function Parent(name){
this.friends=['yve','jack','will'];
this.name=name;
}//构造函数定义两个属性
Parent.prototype.sayName=function(){
console.log(this.name);}//原型定义方法
function Child(){
parent.call(this,name);//继承属性,调用parent构造函数时,传入了name参数
this.age=age;
}
//继承方法
Child.prototype=new Parent();//获得了sayName方法
Child.prototype.constructor=Child;
Child.prototype.sayAge=function(){
console.log(this.name);
}
- call()方法和apply()方法
每个函数都包含两个非继承而来的方法:call()方法和apply()方法
相同点:在特定的作用域调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域
不同点:两个方法否可以接受两个参数。
apply()方法第一个是函数运行的作用域(this),另一个是参数数组。
apply(this,argArray); apply(this,[3,4]);
call()方法第一个也是函数运行的作用域(this),另一个参数必须一一列举出来。
call(this,arr1,arr2..arrn); call(this,3,4);
- 事件流
IE事件流:事件开始是由最具体的节点元素接受,然后逐级向上传播到不具体的节点。
Netscape communicator事件流:不太具体的节点元素先接受到事件,然后逐级向下,最具体的节点元素最后接受到事件。