@xudongh
2017-03-20T22:11:32.000000Z
字数 6431
阅读 1155
前端开发
ECMAscript变量包含两种不同数据类型的值:
基本类型:
var num1 = 5;
var num2 = num1;
//num1中的5和num2中的5是完全独立的
引用类型:复制的是指针
var obj1 = new Object();
var obj2 = obj2;
obj1.name = "Daniel";
alert(obj2.name); //"Daniel"
所有函数的参数都是按值传递的。
对于传递对象类型的参数:
function setName(obj){
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"
如果person是按引用传递的,那么person就会自动被修改为指向其name属性值为"Greg"的新对象。但是,当接下来再访问person.name时,显示的值仍然是"Nicholas"。这说明即使在函数内部修改了参数的值,但原始的应用仍然保持不变。实际上,当在函数内部重写obj时,这个变量引用的就是一个局部对象了,而这个局部对象会在函数执行完毕后立即被销毁。
typeof
:确定一个变量是字符串、数值、布尔值、还是undefined。
instanceof
:确定一个变量是什么类型的对象。
console.log(person instanceof Object); //变量person是Object的实例吗?
console.log(color instanceof Array); //变量color是Array的实例吗?
某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。
每个函数都有自己执行环境。
如果初始化变量时没有使用var声明,该变量会自动被添加到全局环境中。
解除引用:一旦数据不再有用,最好通过将其值设置为null来释放其引用。
function Person(name){
//...
}
var person1 = Person("Daniel");
//手动解除Person的引用
person1 = null;
访问对象属性的两种方法:
数组的每一项都可以保存任何类型的数据。
所有对象都具有toLocaleString()
、toString()
、valueOf
方法。
join()方法可以用时不同的分隔符来构建成字符串,join()方法只接收一个参数:
var colors = ["red", "green", "blue"];
cosole.log(colors.join("||")); //red||green||blue
栈方法、队列方法:
重排序方法:
操作方法:
注:concat()方法可由ES6扩展运算符来代替使用:
//ES5
[1,2].concat([2,3,4]) //[1,2,2,3,4]
//ES6
[1,2, ...[2,3,4]] //[1,2,2,3,4]
位置方法:
var numbers = [1,2,3,4,5,5];
console.log(numbers.indexOf(3)) //2
迭代方法:
5个迭代方法,每个方法都接收两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象——影响this的值。传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。
归并方法:
2个归并方法,迭代数组的所有项,然后构建一个最终返回的值。2个方法都接收两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值。传入方法的函数接收4个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上。
var values =[1,2,3,4,5];
var sum = values.reduce(function(prev , cur , index, array){
return prev + cur;
});
console.log(sum); //15
创建日期对象:
var now = new Date();
如果不传入参数,日期对象会自动获得当前日期和时间。
分析代码运行时间:
//取得开始时间
var start = Date.now();
//调用函数
doSomething();
//取得停止时间
var stop = Date.now(),
result = stop - start;
也可用console.time
、console.timeEnd
来实现这一过程:
//开始
console.time("string");
//调用函数
doSomething();
//结束
console.timeEnd("string");
//控制台输入如下:
string: 12.00ms
ECMASCript通过RegExp来支持正则表达式。
函数名是指向函数对象的指针,不会某个函数绑定。
JS函数没有重载。
函数内部有两个特殊的对象:arguments和this。
arguments包含着传入函数中的所有参数。这个对象有一个callee属性,该属性是一个指针,指向拥有这个arguments对象的函数。
//阶乘算法
function factorial(num){
if(num <= 1){
return 1;
} else {
return num * factorial(num-1)
}
}
//消除函数名自耦合
function factorial(num){
if(num <= 1){
return 1;
} else {
return num * arguments.callee(num-1)
}
}
this引用的是函数据以执行的环境对象。
函数对象有一个caller属性,这个属性保存着调用当前函数的函数引用。
注意:该属性是函数对象的属性,而不是arguments的属性。
function outer(){
inner();
}
function inner(){
console.log(inner.caller);
//或者 console.log(arguments.callee.caller);
}
outer();
//由于outer()调用了inner(),因此控制台输出为outer()函数的源代码
每个函数都包含两个属性:length和prototype。
函数的方法:apply()、call()和bind()。
- apply():接收两个参数,在其中运行函数的作用域和参数数组。
- call():接收多个参数,在其中运行函数的作用域和多个参数。
- bind():这个方法创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
window.color = "red";
var o = { color: "blue" };
function sayColor(){
console.log(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
//等价于
o.objectSayColor = sayColor;
o.objectSayColor();
为了便于操作基本类型值,ECMAScript还提供了2个特殊的引用类型:Boolean、Number和String。
var s1 = "1234";
console.log(s1.substring(2)); //34
引用类型和基本包装类型的区别:
用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中;
自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁,这以为这我们不能在运行时为基本类型值添加属性和方法。
注意:使用new调用基本包装类型的构造函数,与直接调用同名的转型函数是不一样的。
var number = Number(10);
console.log(typeof number); //number
var obj = new Number(10);
console.log(typeof obj); //object
方法:
- toString():传递一个表示基数的参数,告诉它返回几进制数值的字符串形式。
- toFixed():按指定的小数位返回数值的字符串表示。
- toExponential():返回以指数表示法表示的数值的字符串形式,接受的参数是指定的小数位数。
- toPrecision():返回固定大小格式或者指数格式,具体看哪种格式最合适。接受的参数表示数值的所有数字的位数。
一些方法:
下面这两个方法用于搜索给定的子字符串,返回该子字符串的索引值。
lastIndexOf()
trim():创建一个字符串的副本,删除前置及后缀的所有空格。
toLowerCase():转为小写。
字符串匹配方法:
ECMAScript有两种属性:数据属性和访问器属性。
1.数据属性
要修改属性默认的特性,必须使用ECMAScript 5的Object.defineProperty()方法。这个方法接收三个参数:
var person = {};
Object.defineProperty(person, "name", {
writable: false,
configurable: false,
value: "Nicholas"
})
console.log(person.name); //"Nicholas"
person.namre = "Greg";
console.log(person.name); //"Nicholas"
delete person.name;
console.log(person.name); //"Nicholas"
在调用Object.defineProperty()方法时,如果不指定,configurable、enumerable和writable特性的默认值都是false。
2.访问器属性
在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;
在写入访问器属性时,会调用setter函数,这个函数负责决定如果处理数据。
访问器属性有4个特性:
访问器不能直接定义,必须使用Object.defineProperty()来定义。
var book = {
_year: 2017, //_下划线是一种常用的记号,用于表示只能通过对象方法访问的属性。
edition: 1
};
Object.defineProperty(book, "year", {
get: function(){
return this.year;
},
set: function(newValue) {
if (newValue) {
this._year = newValue;
this.edition += newValue - 2017;
}
}
});
book.year = 2018;
console.log(book.edition); //2
只指定getter函数意味着属性不能写,尝试写入属性会被忽略。
只指定setter函数意味着属性不能读。尝试读取属性会返回undefined。
利用Object.defineProperties()方法可以通过描述符一次定义多个属性。这个方法就收两个对象参数:
使用Object.getOwnPropertyDescriptor()方法可以取得给定属性的描述符。