Idle Works, Idle Thoughts

JavaScript 学习笔记

if语句中,逻辑与/或用&&||,没有and和or这样的关键字。另有关键字:true/false。

页面加载后即运行的JavaScript代码,即定义一个匿名函数,并运行它:

(function(){})();

简单调试技术

1. 通过console.log()在控制台输出调试信息:

console.log("hello world");

2. 通过alert()在浏览器弹出一个框,输出提示信息。

3. 通过document.write()输出到当前的HTML页面中。

document.write("hello world!");

4. 通过下面这段代码,把日志发送到Server:

var sender = new XMLHttpRequest();
sender.open("GET", "client-log.php?log=" + msg);
sender.send();

JavaScript语法基础

switch/case语句:

switch(expression) {
    case n:
        /* codes */
        break;
    case m:
        /*  codes */
        break;
    default:
        /*  codes*/
}    

try…catch语句:

try {
    throw new Error("Unkonw Error.");
} catch(e) {
    console.log(e.message);
}

字符串

JavaScript字符串是不可变的(immutable),String类所定义的方法都不能修改字符串的内容。如果涉及修改,都是返回全新的字符串。

replace()字符串替换。注意没有在原字符串上替换,而是返回了替换后的值:

s = "hello berlin";
s = s.replace("berlin", "james");

replace()执行替换。但注意,s.replace("a", "b");只会替换第一次出现的a,要所有的a都替换为b,应该用s.replace(/a/g, "b");这样的写法。

indexOf()进行字符串搜索,如果没有找到子串则返回-1.

String.prototype.include = function(s) {
    return this.indexOf(s) != -1;
};

var s = "Welcome to my world!";
if(s.include("world")) {
    console.log("it works!");
}

search()进行正则表达式搜索,如果没有找到子串则返回-1.

if(s.search("world")) {
    console.log("find it");
}
if(s.search("/Welcome/")) {
    console.log("find it");
}
if(s.search("/welcome.*world/i")) {
    console.log("find it");
}

JavaScript 中没有 startsWith()endsWith() 这样的实用函数,可以自己添加:

if (typeof String.prototype.startsWith != 'function') {
    String.prototype.startsWith = function (prefix){
        return this.slice(0, prefix.length) === prefix;
    };
} 

if (typeof String.prototype.endsWith != 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}

注意 startsWith() 的实现没有使用 indexOf(),因为 indexOf() 会扫描整个字符串。

数组

简单构造数组。

var notebooks = ["book", "movie", "story"];

使用push()往数组附加数据:

notebooks.push("song");
console.log(notebooks);     // ["book", "movie", "story", "song"]。

使用shift()弹出第一个元素,使用pop()弹出最后一个元素:

var head = notebooks.shift();
var tail = notebooks.pop();
console.log(head, tail, notebooks);     // book song ["movie", "story"]

使用unshift()往数组开头出添加数据:

var arr = [1, 2];

arr.unshift(0);         // [0, 1, 2]
arr.unshift(-2, -1);    // [-2, -1, 0, 1, 2]
arr.unshift([-4, -3]);  // [[-4, -3], -2, -1, 0, 1, 2]

判断一个元素是否存在于数组中:

arr.indexOf(2);         // 找不到则返回-1

对象

一些对象的构造示例:

var obj = {};
var point = { x:0, y:0 };
var circle = { 
    x : point.x, 
    y : point.y, 
    radius:2 
};
var user = {
    "name" : "berlinix",
    "age" : 26
};

在创建对象后,可以随时增删对象属性。添加属性:

user.mail = "unkown@berlinix.com";
user["city"] = "beijing";

添加(访问)属性有2种方法,一种为obj.member,另一种为obj["member"]。前一种是半动态的,属性名是标识符,可以在代码中为对象任意添加属性,但必须硬编码;后一种是完全动态的,属性名是字符串,可以在运行时为对象添加属性。像obj["member"]这样的对象,我们也称作关联数组,类似Perl的哈希。

JavaScript中函数也是对象,因此可为函数添加属性,如:

id_factory.id = 0;
function id_factory() {
    return id_factory.id++;
}

以上代码实现了每次调用id_factory()返回新的数值功能(更好的实现是用闭包)。

对象属性是动态生成的,可以用for in来遍历对象所有属性:

function to_str(user) {
    var s = "";
    for(var name in user) {
        s += name + "\n";
    }
    return s;
}

要测试对象是否有某个属性,可以用in表达式或直接与undefined对比:

if("website" in user) { }
if(user.website !== undefined) { }

删除对象属性用delete运算符。delete后,for/in不会枚举该属性,in也不会检测到该属性。

Window对象

常见Window对象方法列表:

常见用法:

alert("hello, world!");

var ret = confirm("submit your order?");
if(ret == true) { alert("submit!"); }
else { alert("don't submit!"); }

prompt(msg, default_value);
var username = prompt("Input your name", "myname");
alert("hello, " + username);    

获取当前浏览页面的文件名:

var page = window.location.pathname.split("/").pop();        

document对象

获取一个div的内容

document.getElementById("country").innerHTML;

setTimeout()函数

setTimeout()是一个异步函数。

console.log(1);
setTimeout(function() { console.log(2); }, 500);
console.log(3);

这段代码的输出是:1、3、2. 注意setTimeout()并没有阻塞主线程。

CORS跨域请求

在Server端的响应报文中需要添加:

Access-Control-Allow-Origin:*

node.js中可以这样做:

res.setHeader('Access-Control-Allow-Origin','*');