zoukankan      html  css  js  c++  java
  • ppk on javascript 笔记(五)

    第5章 核心

    1999年ECMA将核心标准化为ecmascript(http://www.ecma-international.org/publications/standards/Ecma-262.htm),对该规范最重要的评论来自Douglas Crockford(http://crockford.com/javascript/recommend.html)关于Crockford更多的文章可参考(http://dancewithnet.com/2009/03/29/douglas-crockford/

    基础知识

    区分大小写

    语句和分号:分号表示一条语句结束;对于一行代码的语句,不管是否以分号结尾,javascript会自动插入分号;当使用if,for或while控制结构时,可以不用分号结束。

    注释

    代码块:{};当if, while, for只包含一条语句时,可以省略{};函数主体必须在{}中。

    运算符:优先级;返回值;赋值运算符返回当前的值,因此可以使用var a=b=1;

    值:函数也可以用来赋值(注意使用为值时不应该再带括号)。

    数据类型

    javascript有4种重要的数据类型:数字、字符串、布尔型和对象;4种小数据类型:undefined、null以及表示“不存在”的两种说法。

    null意味着无值,下面不会报错,显示为null,但当我们使用null值时就会报错--缺少对象。

    var x = document.getElementById('test');
    alert(x);

    undefined发生在3种情况:声明了一个变量,但没有赋值;访问一个对象尚未声明的属性;定义了函数的参数,但没有传值给它。

    alert(y);
    var x; alert(x);
    alert(window.y);

    第一条语句会报错:y未定义;第二行和第三行则会显示undefined。

    typeof运算符表示一个值的数据类型,它有两个特例:

    var x =1; alert(typeof x);
    var y ='1'; alert(typeof y);
    var z =true; alert(typeof z);
    function f() {}
    alert(
    typeof(f));
    alert(
    typeof(null));

    第一行返回number,第二行返回string,第三行返回boolean。 

    函数使用typeof时返回function,null则返回object。

    数据类型转换:javascript会根据需要将一种类型解释为另一种类型,原类型并没有改变。如:

    var a = 2;
    var b ='3';
    var c = a * b;

    a是一个数字,b是一个字符串,在做乘法运算时,将b解释为数字,结果c是一个数字,值为6,b并没有改变,仍是一个字符串。

    上面的alert(x),实际上也是把null解释为字符串,然后输出。

    当字符串不能被解释为数字时,返回NaN.

    使用+时,总是解释为连接,而不是加法运算。

    转换为布尔型时,null, undefine, 数字0, NaN, 空字符串''被转换为false,其他所有的值被转换为true。

    显式的数据类型转换,如:x1或者-0将字符串转换成数字,+''将转换成字符串,使用!!转换成布尔型。

    普通运算符

    * - / %及*=等,++和--同样区分前后,=赋值运算符返回被赋予的值,==相等运算符,===等同运算符要求数据类型一致,同样!==不等同运算符也针对数据类型。

    比较运算符总是先将变量解释为数字进行比较,若有一个不能解释为数字,则按照第一个字母顺序进行比较,后面的大于前面的,小写的大于大写的(类似ascii)

    条件运算符?:

    变量

    变量命名习惯采用低驼峰命名规则(lowerCamelCase),W3CDOM也如此命名,命名时不要使用保留字。

    允许对一个未声明的变量直接赋值,这个变量会自动声明,但不允许直接使用未声明的变量,最好使用var显示声明以保持代码清晰。

    按作用域分为全局变量和局部变量,没有块作用域,当在函数体中用var显式声明或作为函数的参数时为局部变量,其他情况如在函数体内未用var声明而直接使用或在函数体外声明的都是全局变量,尽量使用局部变量。

    处理数字

    不区分整数和浮点数,在使用浮点数时会产生舍入误差的bug,因此浮点数运算的结果在显示之前要先进行舍入。0.5可以简写为.5s

    以0开头的数字为8进制,以0x开头的数字为16进制。

    Math对象:

    取整的三种方法:Math.round(), Math.floor(), Math.ceil(),同样适用于负数;

    Math.random()用于产生0~1的随机数;

    Math.abs()取绝对值。

    n.toFixed(2)将数字n转换成一个拥有固定位数的字符串,要求n必须为number类型,否则会报错;它返回字符串。

    全局方法parseInt(x)和parseFloat(x)将字符串转换为数字,它逐字符检查字符串,直接遇见非数字字符为止,当第一个字符非数字时才返回NaN,而上面的显式转换则要求字符串必须全部为数字,(注意16进制的x和float的.也是允许的)。

    与字符串打交道

    习惯上适用单引号表示字符串,允许使用双引号,\为转义符,+为连接符。

    x.length用于取字符串的长度,这是字符串对象的一个属性,且是只读的。

    x.indexOf('a')和x.lastIndexOf('a')用于检索,它返回的索引从0开始,未检索到时返回-1,可以指定检索开始的位置,如x.indexOf('a', 2), x.lastIndexOf('a', x.length-1)。

    x.charAt(9)返回指定位置的字符,索引从0开始。

    x.substring(9)或x.substring(9, 11)返回开始位置和结束位置之间的字符串,索引从0开始。

    x.split('c')用指定的分隔符将字符串转换为数组,分隔符本身并不出现。

    x.toLowerCase()和x.toUpperCase()用于大小写转换。

    处理布尔值

    布尔型数据只有两个:true和false。

    逻辑运算符|| && !,注意javascript也包含逐位运算符&和|。

    if(!document.styleSheets)对象检测时,若浏览器不支持这种方法,即为一个不存在的对象null,它被转换为false。

    逻辑运算符||和&&并不返回布尔值,而是返回运算中最后一次计算的表达式的值。

    例如,应用这个方法,我们可以使用来取得事件目标

    var evtTarget = evt.target || evt.srcElemnt;

    大多数的浏览器将事件目标保存在evt.target中,而IE保存在srcElement中,当evt.target非null时,则返回,否则继续计算srcElement。&&用法也如此。

    控制结构

    if ... else if ... else ...

    switch(...) { case ..: .. break; default:... } 注意,switch允许任意的数据类型(其他语言如java只允许对数字),但switch与case比较时,不会进行数据类型的转换。

    四种循环语句:for, while, do/while, for in

    for, while 条件检测总在循环体执行之前,而do/while先执行后检测。

    当while陷入无限循环时,浏览器会提示是否终止代码运行。

    do { ...} while(..); 最好在do/while的最后加一个分号。

    break与continue。

    当在嵌套循环中想跳出外层循环时,使用标签是可行的,事实上,任何语句都可以标志为标签。

    myloop:for(var i=0; i<x.length; i++) {
    for(var j=0; j<x.length; j++) {
    if([something is the case]) continue myloop;
    }
    }

    try/catch用来确保用户不会看到错误信息。

    函数

    定义一个函数 function f() {} 或 var f = function() {}。

    函数可以直接return;或return任意一个数据类型。

    var g=f; 则定义了函数的一个引用,可以运行g();。

    当将函数作为一个值时不能使用(),而()运算符则命令函数执行。

    函数可以内嵌函数,使用内嵌函数时,需注意局部变量的作用域:

    function init() {
    var message =' clicked ';
    var x = document.getElementsByTagName('a');
    for (var i=0; i<x.length; i++) {
    x[i].onclick
    =function() {
    x[i].firstChild.nodeValue
    = message;
    }
    }
    }

    函数运行在被定义的作用域中,而不是执行它们的作用域中。这意味着内嵌函数可以访问所有它的父函数的局部变量,即使父函数在内嵌函数调用前就早已执行。

    在此,内嵌函数访问了父函数的局部变量i和x,但是i发生了错误,程序报错。这是因为内嵌函数只能访问到局部变量的最终值;

    假设x.length=9,那么init函数执行结束后i的值为10,以后当内嵌函数触发时就会使用这个i,于是使用了x[10]这个null值,从而报错;

    正确的写法应该是 x[i].onclick = function() { this.firstchild.nodeValue = message; }

    对象

    对象用来保存彼此相关联的变量和函数,也就是一组属性的集合,值为函数的属性称作方法,点运算符用来获取一个属性或方法。

    允许自定义对象 var t = new Object(); t.a = 1; t.b = function() {}

    可以用字面量来定义对象 var t = { a:1, b:fucntion() {} }属性间用逗号隔开。

    访问一个属性没有什么害处,不管对象是否有这个属性,但是访问一个方法的同时也尝试去执行它,例如

    function stopProp(e) {
    if(e.stopPropagation) {
    e.stopPropagation();
    }
    e.cancelBubble
    =true;
    }

    对停止事件传播,W3C标准的浏览器需执行stopPropagation方法,而IE只需将cancelBubble设为true,上面这种写法是规范的,直接访问不存在的方法会报错,而对于W3C标准的浏览器则只是多创建一个值为true的属性而已,但是这个属性对IE来说却是一个预定义属性,改变预定义属性的值便会引起一些相应的动作。

    允许创建自己的属性。

    this关键字出现在方法中(js不区分方法和函数),用来引用定义该方法的对象。

    属性和变量也是对等不区分的,全局变量也即全局对象window的属性。

    关联数组

    下面两种表达式等价的:object.property; object['property']; 同样的这也是等价的:object.method(); object['method']();

    使用点符号时,后面的属性名或方法名是固定的字符串常量,而使用方括号则可以使用变量随意更改属性的名字。

    关联数组是一个数组,它允许通过字符串作为值的名字来找到某一个确定的值,这些字符串叫做关键字。

    for in用来遍历一个关联数组,例如

    var t = {
    a:
    2,
    b:
    '2',
    c:
    function() {
    alert(
    this.a*this.b);
    }
    }
    for(var i in t) {
    alert(i
    +':'+ t[i]);
    }

    弹出的三个信息分别为a:2,b:2和c:fuction() { alert(this.a*this.b); }。注意到i表示了关键字,而方括号使用了变量i来获取t的属性(点符号是行不通的,t.i表示t的i属性),同时也可以看到a的值数字2被转换成了字符串2。

    数组

    数组是一个用数字来索引的值的集合,索引数从0开始,例如

    var t =new Array();
    t[
    0] ='2';
    t[
    2] =3;
    t[
    5] =function() {
    alert(
    this[0] *this[2]);
    }
    t[7] = new Array();
    t[7][5] = false;
    t[
    5]();
    alert(t[
    1]);

    这定义了一个稀疏数组,它只定义了几个元素,对于其他元素根本就没有创建它们,访问时会返回undefined,就好像一个未定义的属性一样。运行t[5]()会弹出6。t[7]则是一个嵌套数组。

    除了上述定义方法,数组还有两种表示法:

    var s =new Array(0, 1, '2', 'three', false);
    var t = [0, 1, '2', 'three', false];

    这两种方法无法指定特定的索引序列,其中后一种方法数组字面量常用。

    如getElementsByTagName获得的节点列表并不是数组,可以看做为缺乏所有定义在数组对象上的有用方法的只读数组,以后再介绍。

    length属性表示数组长度,数组长度总是最大的索引数加1,包括稀疏数组。增加减少元素会更新length的值,对length属性赋值会改变数组,访问超出长度的索引会返回undefined。

    设t是一个数组,有四种方法增减元素:t.unshift(x);用来插入一个起始元素,t.shift();删除一个起始元素,t.push(x)插入一个末尾元素,t.pop()删除一个末尾元素。

  • 相关阅读:
    static变量的生命周期
    关于C++的new是否会对内存初始化的问题
    行列式的本质是什么?
    C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝
    C++拷贝(复制)构造函数详解
    随机生成指定长度字符字符串(C语言实现)
    【npm】npm install的报错
    【HTTP】http请求url参数包含+号,被解析为空格
    【ngx-ueditor】百度编辑器按下Shift键不触发contentChange事件
    【Angular】No component factory found for ×××.
  • 原文地址:https://www.cnblogs.com/bloodmage/p/1758573.html
Copyright © 2011-2022 走看看