《JavaScript核心概念及实践》——1.2 JavaScript语言特性

    xiaoxiao2024-03-14  15

    本节书摘来自异步社区《JavaScript核心概念及实践》一书中的第1章,第1.2节,作者:邱俊涛著,更多章节内容可以访问云栖社区“异步社区”公众号查看

    1.2 JavaScript语言特性

    JavaScript是一门动态的、弱类型、基于原型的脚本语言。在JavaScript中“一切皆对象”,在这一方面,它比其他的面向对象的语言来得更为彻底。即使作为代码本身载体的函数(function),也是对象,数据与代码的界限在JavaScript中已经相当模糊。虽然它被广泛应用在Web客户端,但是其应用范围远远未局限于此。下面就这几个特点分别介绍。

    1.2.1 动态性动态性是指,在一个JavaScript对象中,要为一个属性赋值,我们不必事先创建一个字段,只需要在使用的时候做赋值操作即可。如下例:

    //定义一个对象 var obj = new Object(); //动态创建属性name obj.name = "an object"; //动态创建属性sayHi obj.sayHi = function(){ return "Hi"; } obj.sayHi();

    当不需要一个对象的属性时,我们可以很轻易地将其从对象上删除。

    obj.name "juntao" delete obj.name obj.name undefined

    假如我们使用Java语言,代码可能会是这样:

    class Obj{ String name; Function sayHi; public Obj(Sting name, Function sayHi){ this.name = name; this.sayHi = sayHi; } } Obj obj = new Obj("an object", new Function());

    可以看出,在静态语言中,需要预先定义好对象需要什么属性,属性自身的类型是什么,当定义完成之后,对象的结构就定下来了,之后都保持这种结构而无法更改。通常对象可能会继承一些自己用不到的方法,而且也无法删除。

    另一个有趣的例子是动态地访问一个JavaScript对象的属性。

    var key = "property"; print(key); "property" var obj = { property: "my property" } print(obj[key]); "my property"

    应该注意到key是一个变量,其值为“property”,当执行obj[key]时,key被求值为“property”,然后去除obj["property"],这个特性可以使得代码更加简洁清晰,比如可以动态地从代码中生成对象的属性名,然后去除属性值等。

    1.2.2 弱类型与Java、C/C++不同,JavaScript是弱类型的,它的数据类型无需在声明时指定,解释器会根据上下文对变量进行实例化,比如:

    //定义一个变量s,并赋值为字符串 var s = "text"; print(s); //赋值s为整型 s = 12+5; print(s); //赋值s为浮点型 s = 6.3; print(s); //赋值s为一个对象 s = new Object(); s.name = "object"; print(s.name);

    结果为:

    text 17 6.3 Object

    在JavaScript中,类型是和值关联的,而不是和变量关联。弱类型具有很大的灵活性,在定义变量时无须显式声明。不过,弱类型也有其不利的一面,比如在开发面向对象的JavaScript的时候,没有类型的判断将会是比较麻烦的问题,不过我们可以通过别的途径来解决此问题。

    1.2.3 面向对象虽然与主流的面向对象语言中的面向对象的概念大相径庭,但是在JavaScript中,一切都是对象!只不过JavaScript中,这一点更为彻底一些,甚至用以表达逻辑的函数/代码本身也是对象,比如代码本身可以作为参数传递给其他的代码。

    var array = [1, 2, 3, 4, 5]; array.map(function(item){ return item * 2; });

    运行结果如下。

    [2, 4, 6, 8, 10]数组array中有5个元素,每个元素是一个数字。数组的map方法会接受一个匿名函数,这样对于数组中的每个元素,都会调用这个匿名函数(返回元素乘以2的值),最后把结果放入结果数组。有意思的是此处的map,它可以接受函数作为参数。map函数可以处理更为复杂的场景,比如数组中的每个元素都是一个复杂对象。

    var staff = [ {name: 'abruzzi', age: 24}, {name: 'bajmine', age: 26}, {name: 'chris', age: 25} ]; staff.map(function(item){ return item.name.toUpperCase(); });

    运行结果如下。

    ['ABRUZZI', 'BAJMINE', 'CHRIS']在上例中,map用以将数组staff中的每个元素的name属性取出,转换为大写字母,并生成新的数组,而将对于那些不关心的其他属性(比如此处的age)排除在结果集之外。

    另一个例子是与map很类似的函数filter,用于过滤数组中满足某些条件的元素,filter的使用方法与map一样,也接受一个函数。

    staff.filter(function(item){ return item.age > 24; });

    这样结果中仅包含age大于24的条目。

    [ {name: 'bajmine', age: 26}, {name: 'chris', age: 25} ]

    这两个例子中,可以看到函数可以像其他任何数据类型(字符串、数字)那样,被轻易地传递给其他函数。在JavaScript中一切都是对象。

    1.2.4 解释与编译通常来说,JavaScript是一门解释型的语言,特别是在浏览器中的JavaScript,所有的主流浏览器都将JavaScript作为一个解释型的脚本来进行解析。然而,这并非定则,在Java版的JavaScript解释器Rhino中,脚本可以被编译为Java字节码。Google的V8引擎则直接将JavaScript代码编译为本地代码,无需解释。

    解释型的语言有一定的好处,即可以随时修改代码,无需编译,刷新页面即可重新解释,可以实时看到程序的结果,但是由于每一次都需要解释,程序的开销较大;而编译型的语言则仅需要编译一次,每次都运行编译过的代码即可,但是又丧失了动态性。

    相关资源:JavaScript王者归来
    最新回复(0)