JavaScript-ES5

什么是 ECMAScript 5?

ECMAScript 5 is also known as ES5 and ECMAScript 2009

This chapter introduces some of the most important features of ES5.

ECMAScript 5 Features(特性)

These were the new features released in 2009:

  • The "use strict" Directive
  • String.trim()
  • Array.isArray()
  • Array.forEach()
  • Array.map()
  • Array.filter()
  • Array.reduce()
  • Array.reduceRight()
  • Array.every()
  • Array.some()
  • Array.indexOf()
  • Array.lastIndexOf()
  • JSON.parse()
  • JSON.stringify()
  • Date.now()
  • Property Getters and Setters
  • New Object Property Methods

新特性之 The "use strict" Directive

"use strict" 定义js代码以严格模式执行,使用严格模式,你就不可以使用未声明的变量了。

你可以在所有的程序中使用严格模式,它帮助你写出干净的代码,就像不使用未声明的变量一样。

另外"use strict"仅仅是一个字符串表达式,那些过时的浏览器也不会抛出错误,即使它们不知道它。

新特性之 String.trim()

String.trim() 可以删除一个字符串两端的空白内容。

var str = "       Hello World!        ";
alert(str.trim());

新特性之 Array.isArray()

检查一个对象是否是数组

 var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.info(Array.isArray(fruits))

新特性之 Array.forEach()

对数组的每个元素都调用一次函数

var numbers = [45, 4, 9, 16, 25];
numbers.forEach(function(item,index){
        console.info(item,index)
});

新特性之 Array.map()

对数组的每个元素都调用一次函数,返回一个新的元素,最终这些新的元素组合成新的数组

var numbers = [45, 4, 9, 16, 25];
numbers=numbers.map(function(item,index){
        console.info(item,index)
        return item*2;
});
console.info(numbers)

新特性之 Array.filter()

从一个数组取出大于18的数字组成一个新的数组

var numbers = [45, 4, 9, 16, 25];
var over18 = numbers.filter(function(value,index){
        console.info(value,index);
        return value>18;
});
console.info(over18)

新特性之 Array.reduce()

对一个数组求和。

var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduce(function(total,value,index){
        console.info(value,index);
        return total + value
});
console.info(sum)

ps:map和reduce在其他动态语言中也是经常出现的。

新特性之 Array.reduceRight()

和上面一样的功能,只是从最后一个数字开始累加。

var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduce(function(total,value,index){
        console.info(value,index);
        return total + value
});
console.info(sum)

新特性之 Array.every()

检查:所以的数字都大于18

var numbers1 = [45, 4, 9, 16, 25];
var allOver18=numbers.every(function(value){
        return value>18;
});
console.info(allOver18)

新特性之 Array.some()

检查:有部分数字大于18

var numbers1 = [45, 4, 9, 16, 25];
var allOver18=numbers.some(function(value){
        return value>18;
});
console.info(allOver18)

新特性之 Array.indexOf()

在一个数组中查询一个元素的位置,查不到返回-1。

var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.info(fruits.indexOf("Apple"));
console.info(fruits.indexOf("Apple_Unknown"));

新特性之 Array.lastIndexOf()

同上,只是从右侧开始查找。

var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.info(fruits.indexOf("Apple"));
console.info(fruits.indexOf("Apple_Unknown"));

新特性之 JSON.parse()

把字符串解析成js对象

var str='["Banana","Orange","Apple","Mango"]'
var fruits=JSON.parse(str)
console.info(fruits)

新特性之 JSON.stringify()

把对象转成字符串

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var str=JSON.stringify(fruits)
console.info(str)

新特性之 Date.now()

时间毫秒数,可以不用new了。

console.info(new Date().getTime(),Date.now())

新特性之 Property Getters and Setters

这个特性可以定义看上去像get和set的属性方法,比较特别的是调用getter不需要加括号,调用setter也不需要加括号,反而的是等于号,
这个对于java程序员来说,是需要适应的。
既然有了setter,getter,那就可以在里面加入其他代码,实现基于数据驱动的特性。

var person = {
    firstName: "John",
    lastName : "Doe",
    get fullName() {
        return this.firstName + " " + this.lastName;
    },
    get UpperFullName() {
        return this.fullName.toLocaleUpperCase();
    }
};
for(var p in person){
        console.info(p,person[p])
}

新特性之 New Object Property Methods

Object 的新方法,可以修改一个对象属性的值或者元数据信息。

// Create an Object:
var person = {
    firstName: "John",
    lastName : "Doe",
    language : "NO", 
};
// Change a Property:
Object.defineProperty(person, "language", {
    value: "EN",
    writable : true,
    enumerable : true,
    configurable : true
});
// Enumerate Properties
for (var p in person) {
    console.info(p,person[p])
}

// Change a Property:
Object.defineProperty(person, "language", {
get : function() { return language },
set : function(value) { language = value.toUpperCase()}
});

person.language = "cn";
// Enumerate Properties
for (var p in person) {
    console.info(p,person[p])
}

ECMAScript 5 Syntactical Changes(语法改进)

Object的其他新方法

// Adding or changing an object property
Object.defineProperty(object, property, descriptor)

// Adding or changing many object properties
Object.defineProperties(object, descriptors)

// Accessing Properties
Object.getOwnPropertyDescriptor(object, property)

// Returns all properties as an array
Object.getOwnPropertyNames(object)

// Returns enumerable properties as an array
Object.keys(object)

// Accessing the prototype
Object.getPrototypeOf(object)

// Prevents adding properties to an object
Object.preventExtensions(object)
// Returns true if properties can be added to an object
Object.isExtensible(object)

// Prevents changes of object properties (not values)
Object.seal(object)
// Returns true if object is sealed
Object.isSealed(object)

// Prevents any changes to an object
Object.freeze(object)
// Returns true if object is frozen
Object.isFrozen(object)

Property access [ ] on strings

var str = "HELLO WORLD";
str.charAt(0);            // returns H

var str = "HELLO WORLD";
str[0];                   // returns H

Trailing commas in array and object literals

对象末尾可以保存逗号

person = {
  firstName: "John",
  lastName:" Doe",
  age:46,
}

数组后面可以保留逗事情

points = [
  1,
  5,
  10,
  25,
  40,
  100,
];

Multiline string literals

字符串可以跨多行了

"Hello 
Dolly!";

Reserved words as property names

保留关键字现在可以作为属性名了

var obj = {name: "John", new: "yes"}

复习一下 ECMAScript 5 之前的知识

函数作用域中的this

先看一段代码

var Person=function(name){
        this.name=name;
        var sayName=function(){
                console.info('im '+ name)
                console.info('im '+ this.name) // this是window
        }

        this.sayName=function(){
                sayName();
                console.info('i am '+ name)
                console.info('i am '+ this.name)
        }
}

var person=new Person('jack');
person.sayName();
console.info('--------------------------------')
person.sayName.call({name:'lucy'});

运行一下,能够解释清楚,就可以了,需要明白几点:

  • new 出来的对象自动绑定了this,这和java是一样的
  • call和apply可以更改this的绑定
  • 不是new出来,this是顶级作用域中的window

函数作用域链中的变量

var name='jack';
var age=18;
console.info(name,age);
function a(){
        var name='jacka';
        console.info(name,age);
        function b(){
                 var name='jackb';
                console.info(name,age);
        }
        b();
}
a();

另外说明一下,是函数界定了变量,if,swith,while,for并没有,只要这个变量不是在其他函数中定义的,那么它在整个函数内是可见的。

你真的可以解释下面这句吗

for(var i=0;i<4;i++){
        for(var i=0;i<4;i++){
                console.info(i)
        }
}

在一个函数中重复定义一个变量是不会报错的,对一个变量,可多次使用var。

for(var i=0;i<4;i++){
   console.info(i)     
}
console.log('current i value: '+i)
for(var i=0;i<4;i++){
    console.info(i)
}

函数对象

arguments,callee,caller,length,prototype

var getList=function(param1,param2,param3){
        var len=arguments.length;
        for(var i=0;i<len;i++){
                console.info(i,arguments[i])
        }
}
console.info(getList.length)
new getList('a','b','c');
getList('a2','b2','c2')

参数从a传到了b

function a(){
        var args=Array.prototype.slice.call(arguments)
        b.apply({},args);
}
function b(){
        console.info(arguments.length)
        for(var i=0;i<arguments.length;i++){
                console.info(i,arguments[i])
        }
}

a();
a('a');
a('a','b');
a('a','b','c');

callee指向函数自己,可以实现递归,少写了一次自己的函数名称

function fact(n){
     if(n==1){
             return 1;
     }else{
             return n*arguments.callee(n-1)
     }
}

console.info(fact(5))

获取调用者的函数名称

function a(){
        console.info(a.caller.name)
}
function a2(){
        console.info(arguments.callee.caller.name)
}

function w3c(){
        a()
        a2()
}
w3c();
原文地址:https://www.cnblogs.com/BlackSwanYucatan/p/10016052.html