Html5入门教程系列(2)–javascript介绍

14次阅读

说起 html5,可能是近 1 - 2 年最火的技术词汇之一了,由于市场需求爆增,人才也趋之若鹜。javascript 是前端编程中最为重要的技能之一,是学习前端编程必不可少的。本篇介绍javascript,重点从javascript 与其他语言的不同点入手。

理解 javascript

先说一句废话:javascriptjava 没有半毛钱关系。javascript 是 ECMAScript 的一种实现,而后者广泛应用于 web 客户端的编程,除了 javascript 以外,还有 ActionScript 也是 ECMAScript 的实现之一,而 ActionScript 应用于 flash 编程。javascript 大致由三部分组成:ECMAScriptDOMBOM

Html5 入门教程系列(2)--javascript 介绍

  • DOM:即 文档对象模型(Document Object Model),该模型允许通过 javascript 动态修改 html 文档的结构和内容,其重要性甚至超过 javascript 语法本身,可以说如果没有 DOM,javascript 根本没有卵用。例如
<div id="main"></div>

执行如下代码后

var main = document.getELementById('main');
var p = document.createElement('p');
main.appendChild(p);
<div id="main"><p></p></div>
  • BOM:即 浏览器对象模型(Browser Object Model),该模型允许 javascript 有限的控制浏览器本身而不是 html 文档
window.history
window.location
window.navigator.userAgent

javascript 的不同之处

弱类型

与 C ++、C#、java 不同在于,javascript 是弱类型的,一个变量可以赋予任何的类型

var a = 1;
var a = 0.5;
var a = 'str';
var a = "str"; // 双引号和单引号都可以表示字符串
var a = [1,2]; // 数组
var a = function(){} // 函数类型

虽说是弱类型语言,但是类型是存在的,下面列举常见的 javascript 的内置类型

typeof(1) //number 类型
typeof(NaN) // 特殊的 number 类型,表示非数字
typeof("123") //string
typeof(true) //boolean
typeof(window) //object
typeof(document) //object
typeof(null) //object
typeof(eval) //function eval 是个函数
typeof(sss): //undefined 表示变量未定义,当使用一个未定义的变量,这个变量不是 null 也不是 false 更不是 ""(空字串),而是一个特殊的叫 undefined 的表达
typeof(undefined) //undefined 本身也是 undefined

object

object 的使用十分简单,我们可以用 json 形式的字面代码来表达一个 object:

var global = { //Using json-like string to define an object
config: {

   <span class="na">schema</span><span class="p">:</span> <span class="s1">'http'</span><span class="p">,</span>
   <span class="na">port</span><span class="p">:</span> <span class="s1">'8080'</span><span class="p">,</span>
   <span class="na">host</span><span class="p">:</span> <span class="s1">'example.com'</span>

},

getUrl: function(){

  <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">schema</span> <span class="o">+</span> <span class="s1">'://'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">host</span> <span class="o">+</span> <span class="s1">':'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">port</span><span class="p">;</span>

}
}

global.config.schema //'http'
global.config.getUrl() //http://example.com:8080

可以看到,一个对象可以包含任何层次的属性或子对象,甚至,可以包含函数。传统的静态类型语言,往往需要我们事先定义好类型 (class),然后通过实例化调用来生成对象。而 javascript 无需定义这种类型模板。javascript 甚至没有class 的概念。当然,关于这一点,有利也有弊:比如如果在 javascript 中希望反复的生成相同模板的对象,就显的不够优雅了,我们需要使用 原型链继承 来模拟 class 这个概念,后面会详细讲述原型链这个问题。

除了在定义对象的时候可以为所欲为外,我们可以为所欲为的对一个已经存在的对象添加属性、方法,还可以通过 for 循环来遍历对象的属性,比 C#java中反射之类的办法容易太多了。

global.config.path             //undefined

global.config.path = '/api/v1/lessons' //OK
global.config.path // '/api/v1/lessons'

global.config['path'] // '/api/v1/lessons'

for(var name in global.config){ // 遍历对象的属性

<span class="nx">global</span><span class="p">.</span><span class="nx">config</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span>

}

函数

函数在 javascript 中最为常见,然而你可能不知道的是,一个函数实际也是一个对象(一个函数类型的对象实例)。函数的定义有很多种形式,这里我们也可以说实例化一个函数对象有很多种形式:

// 定义一个叫 a 的函数对象
var a = function(args){

}

// 定义一个叫 a 的函数对象,也可以这么简写
function a(args){

}

// 内部实际上是这么工作的,实例化一个 Function 类型的对象
var a = new Function()

// 于是这里其实是实例化了一个匿名函数对象,并将该函数对象作为 click 方法的参数,调用 a.click 方法
a.click(function(){

<span class="p">...</span>

})

调用函数的时候,跟大多数语言类型,使用 (),不过 javascript 也有自己的特殊方式,对于上述示例的a 方法,有如下几种调用形式:

a() // 虽然没有传入参数,但是这样调用是可以的,在 a 内部 args 此时将是 undefined
a('param') // 在 a 内部 args 此时将是字符串 param
a(1,'param') // 即使参数超过 "规定",仍然可以工作,在 a 内部 args 此时将是 number 类型的 1

// 以下两种方式是 javascript 特有的函数调用,call 和 apply 也是可以调用函数的,不同之处是可以控制函数内部的 this 指针
// 这种形式在 javascript 的库中很常见,这里不做展开了
a.call()
a.apply()

逻辑运算和隐式转化

在 javascript 中,null undefined 0 false ""在进行 if 测试时,将为假。其他情况都是真!

var a = new Date();
if(a){
// 此时 a 应该能通过 if 测试
}

//var a = new Date();
if(!a){

<span class="c1">// 由于没有定义 a,所以 a 为 undefined</span>
<span class="c1">// 而!a,就是真 </span>

}

var a = function(){}
if(a){

<span class="c1">// a 是一个函数对象,所以为真 </span>

}

var a = -1
if(a){
// a 为真
}

var a = ''
if(a){
// a 是空字串,所以这里判为假
}

从上面的例子中可以看到,在逻辑真假判断上,javascript 比静态语言松散很多,所以在实际的编程上也带来了很多方便之处,比如这段代码视图判断 a 是否是函数对象,如果是则调用 a:

var a = function(){}
if(a && typeof(a) == "function"){
a();
}

甚至可以去掉 if 关键字写成如下形式:

var a = function(){}
a && typeof(a) == "function" && a();

对于 javascript,第二种写法显然更好,因为它节省了代码本身的长度,也就节省了下载 javascript 时候的时间。如果是用静态编程语言的话,恐怕就啰嗦很多了。如果你不以为然,那么看下面这个更常见的例子:

var a = function(options){

<span class="kd">var</span> <span class="nx">_options</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">if</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="nx">_options</span> <span class="o">=</span> <span class="nx">options</span><span class="p">;</span>
<span class="c1">//use _options</span>
<span class="err">…</span>

}

上面的代码在函数中,为了保证 options 的正确使用(因为在调用 a 的时候甚至可以不传入任何参数),至少保证 options 是一个 object。在很多 javascript 的库中这种代码很常见,通常都写成如下形式:

var a = function(options){

<span class="kd">var</span> <span class="nx">_options</span> <span class="o">=</span> <span class="nx">options</span> <span class="o">||</span> <span class="p">{};</span>
<span class="c1">//use _options</span>
<span class="err">…</span>

}

首先检测传入的 options 是否为真,如果是真,那么_options 自然就赋值为 options,||检测终止;如果 options 为假,那么继续检测 || 后面的 {},并将{} 返回赋值给_options。这个技巧很常用,可以牢记。

关于判等,正如许多弱类型语言一样,javascript 分为 =====

var a = 0;
var b = '0';
a == b //will be true
a === b //will be false

var a = undefined;
var b = null;
a == b //will be true
a === b //will be false
a != b //will be false
a !== b //will be true

数组

数组也是一种 javascript 类型,有如下操作方法:

var a = [1,2,3];
var a = new Array(1,2,3);
a[0] = 1;
for(var i=0; i<a.length;i++)
{

<span class="nx">a</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>

}

a.forEach(function(item,index){
console.log(item + 'is at index of' + index);
})

值得一提的是,a.forEach是 a 对象的一个方法,然而我们在定义 a 对象的时候,并没有给 a 赋予 forEach 函数,这个函数是哪里来的呢?答案是:这个函数是 Array 类型的原型函数,会被 Array 类型的对象继承。关于原型和继承将在后面的内容中详细说明。作为 javascript 介绍章节,就此打住。

练习

最后,来完成一个小练习,javascript 简易计算器:

Html5 入门教程系列(2)--javascript 介绍

你可以从 这里 获得示例代码

正文完