首先声明,我是一个菜鸟。一下文章中出现技术误导情况盖不负责
// ======================================================================
// 第二章 词法结构
// ======================================================================
// * JavaScript 程序是用Unicode字符编写的。
// * 区分巨细写
// * JS会主动给换行的语句插入;来运行。如:
// var article_content = "我们都是神枪手
// 这样可以显示吗?";
// 显然这样是不行的,js会这样来剖析
// var article_content = "我们都是神枪手;
// 这样可以显示吗?";
// 这样就是抛出 "Uncaught SyntaxError: Unexpected token ILLEGAL "
// 这么个错误。意思是 不合法的记号(token)。字符串部分出的问题,没有加引号。
// 所以这种时候就要如下一样换行:
//
// var article_content = "我们都是神枪手"
// + "这样可以显示吗?";
// 这是特别情况,平日如果语句完整,是可以省略的,因为js会主动补上分号剖析。
// 原则:都加分号
// * 标识符(identifier):用来定名变量和函数,就是个名字。
// --字母,下划线,美元符开头--
// 字符串,数字这些都是直接量,是token,变量名和函数名也是token,但是也叫标识符
// 在错误提示中可以看出来。
// ======================================================================
// 第三章 数据类型和值
// ======================================================================
// *基本数据类型:number, string, boolean
// 1/1.50, '高'/"圆圆", true/false
// 特别:null, undefined 既是数据类型也是值
var title = null; var content = undefined;
// note: typeof title == "object", but typeof content == "undefined"
// *复合数据类型:对象 {}/[](也叫数组), 还有一种特别对象是 函数(可以执行代码的对象,喊他就执行代码)
var me = {
name: 'Ronio',
gender: 'M'
};
var you = ['Caty', 'M'];
var other = new Array('高圆圆', 'F');
function callMe() {
log('你好。');
}
// note: typeof me == "object",
// typeof you == "object" also other
// typeof callMe == "function"
// number:
// var num = 2/2.5/0Xff; 零Xff 16进制 = 15*16+15 = 255
// for fun:
// (25).toString(2-36); // 转换为2-36进制的字符串
//
// 特别的数值:
// -- Infinity 无穷大的特别值 2/0 === Infinity, -2/0 == -Infinity
// -- NaN 特别的非数字值 如:0/0 结果是NaN, but 0/0 !==/!= NaN, NaN 跟谁都不等,包含自己
//
// string:
// 转义:\n 换行符; \r 回车符
//
// e.g.
var s = "let's go to watch 高圆圆的第100部电影-吧?"; // 每个字符都是 2Bates 表示的
log(s.length);
var lastChar = s.charAt(s.length - 1);
var sub = s.substring(1, 4);
var i = s.indexOf('a');
// 函数
//
// 内置了一些函数,如Math.sin()等
// 声明和定义:
//
// function square(x) {
// return x*x;
// }
//
// or
//
// lambda函数 / 匿名函数
// var square = function(x) {
// return x*x;
// }
//
// 对象
var image = {
width: '200px',
height: '400px'
};
var img = new Object();
img.width = '200px';
var pic = {'width': 200, 'height': 400}; // 关联数组
// 数组
var a = new Array(); a[0] = 25; a[10] = 'ni hao'; a[11] = function(){return 'Hi.';};
var b = new Array('cool', 2.5, {a: 20, b: 25});
var c = [1, 2, [3, 4, [5, 6]]];
// null and undefined(应用了未声明的变量、已经声明但为赋值的变量、应用了并不存在的对象属性)
// undefined == null , but undefined !== null
// note: void运算符提供了另一种获得undefined值的方法:
// void 是一个一元运算符, 老是返回undefined
// 如:javascript: void (0);
// 经常看到这样的写法吧,<a href="javascript:void(0);"></a>, 其实void(0);不是一个函数哦,写成 void 0; 也是可以的
// 我之前始终以为是!!
//
// 正则表达式
// 两个斜线之间就OK。/^HTML/ or /\bjavascript\b/i
// Error对象
// 每个Error对象拥有一个message属性, throw 和 try那一章去探讨。
//
// 基本数据类型String, Number, Boolean.
// 除了了在eval();中应用有别于 基本类型string,其他和基本类型一样,会主动转换。
// 传给eval()String类型的参数,须要应用.toString()才会和应用string一样。是函数eval()只处置基本类型且不主动转换吗?
//
// ======================================================================
// 第四章 变量
// ======================================================================
// var 声明变量,不能应用delete删除,不应用var,无论在哪直接赋值则为全局变量。
// 只有函数作用域,没有块作用域。
// 原则:变量声明都放开头。
//
// 值和引用,值直接保存在内容中,牢固巨细;引用,无牢固巨细,如数组或对象,赋值时复制的是内存地址而不是内容本身。
//
// JavaScript解释器开始运行时,马上创立一个全局对象,应用预定义的值、函数和对象来初始化这个全局对象,
// 定义的全局变量,实际上就是全局对象的属性。
// 局部变量则是调用对象(call object)的属性,还包含参数。
//
// JavaScript的执行环境和变量作用域当前了解。
// 基础:一个执行环境中有全局对象,全局变量(也就是全局对象的属性),调用对象,局部变量。
// 变量名剖析过程,是查找和执行环境关联一起的作用域链上的对象是不是有这个定义了这个变量。
// 比方:5obj---4obj---3obj---2obj---1obj (这是一个作用域链,*obj就是挂在链条上的对象),
// 当JavaScript开始查询变量X的值时,就开始从1obj-->5obj这样的顺序查找各个对象中是不是定义了这个变量,找到就停。
//
// ======================================================================
// 第五章 表达式和运算符
// ======================================================================
// 运算符
// delete, typeof, void instanceof
//
// === 和 ==
// === :
// 1. 两个值类型不同就不同
// 2. 都是数字,有一个是NaN, 则不等
// 3. 都是布尔值,true true才相等
// 4. 都是字符串,同一位置上的字符完全相同则相同。长度或内容不同就不同。
// 注意:Unicode标准允许用多种方法对同样的字符串停止编码,JavaScript逐一比较字符。
// 这种情况可以应用另一种比较方法String.localCompare() ##去看该方法##
// 5. 引用的是相同对象、数组或函数,则相同
// 6. null null相同,undefined undefined相同
// == :
// 1. 类型相同 看值同不同
// 2. 类型不同 类型转换
// 2.1 null == undefined
// 2.2 数字和字符串,则字符串转数字 '2'==2
// 2.3 有个值为 true 转为 1,有个值为 false 转为 0
// 2.4 一个值是对象, 另一个值是数字或字符串,则对象实验.valueOf(), 然后再实验.toString()。
// 特别:Date对象先实验.toString(), 在.valueOf() --> 输出 timespan 类似 1369232357893
//
// in
// 'attribute' in obj
// '2' in array # 2 是数组下标
//
// instanceof
// obj instanceof classname; # 这里的classname是js对象的.contructor.name, 如果classname为对象,则返回false
//
// && # funny
// 表达式1 && 表达式2 --> 表达式1 可转为false 返回表达式1的值,为true,返回表达式2的值。
// 表达式1 || 表达式2 --> 表达式1 可转为true 返回表达式1的值,为false,返回表达式2的值。
// !
// 一点: 对于任何值应用两次该运算符 !!x 都可以将它转换成一个布尔值。
//
// ======================================================================
// 第六章 语句
// ======================================================================
// throw new Error('some error');
// try/catch/finally
try{
log('语法错误之前发生了什么');
throw new SyntaxError('语法错误');
log('错误以后');
}catch (e){
log(e.constructor.name + e.message);
}finally{
log('我执行了。');
}
// 空语句,最好写注释: for(var i=0; i<10; arr[i++] = 0) /*空语句*/;
//
// ======================================================================
// 第七章 函数
// ======================================================================
//
// 1. function square(x) {
// return x*x;
// }
// 2. var square = function(x){return x*x;}
// 3. var square = new Function("x", "return x*x;");
var square = new Function("x", "log('嘿嘿平方'); return x*x;");
// 函数可以作为数据应用
var operators = {
add : function(x, y){return x+y;},
subtract : function(x, y){return x-y;},
multiply : function(x, y){return x*y;},
divide : function(x, y){return x/y;},
pow : Math.pow
};
function operate(op_name, operand1, operand2) {
if(operators[op_name] == null) {
return 'unknown operator';
}else {
return operators[op_name](operand1, operand2);
}
}
var j = operate('pow', 5, 9); // 5+9=14
// Arguments对象 arguments
// arguments.length 实际参数有几个
// arguments.callee 引用当前正在执行的函数对象
//
(function(x) {
if(x <= 1) return 1;
multiply = x * arguments.callee(x-1);
log("形参个数:"+arguments.callee.length + " VS 实参个数:" + arguments.length); // Function对象的length属性
log(multiply);
return multiply;
})(4, 5);
// 属性prototype, 在new Date 时起作用,详细第八章。
//
// call() 和 apply()
var name = '小高';
function fn() {
log('你好,' + this.name);
}
var obj = {
name: '八戒',
fn : function(){
log('用饭了' + this.name);
}
};
fn(); // window.fn(), this 为 window, window.name 为 小高
obj.fn(); // 吃放了,八戒。obj外部的事
fn.call(obj); // 比方: fn 是大黄蜂,平常是一辆车,call 来变形金刚,他就是变形金刚的一部分,这是说this,就是指变形金刚,而不是天地了。
// ======================================================================
// 第八章 对象
// ======================================================================
//
// 结构函数:
// 1. 由 new 运算符调用。(很好懂得)
// 2. 传递给它的是一个对新创立的空对象的引用,将该引用作为关键字this的值,并
// 对新创立的对象停止适当初始化。结构函数有返回值,则this值所引用的对象就被丢弃了。
function R_area(){}
function R_perimeter(){}
function R_enlarge(){}
function Rectangle(w, h)
{
this.width = w;
this.height = h;
this.area = R_area;
this.perimeter = R_perimeter;
this.enlarge = R_enlarge;
}
var r = new Rectangle(5, 5);
var r1 = new Rectangle(10, 10);
// r, r1 每新建一个对象,就会给对象的每个属性分配内存。如果给 Rectangle类添加X个方法,内存就增加N*X倍。
// 解决办法:原型对象和继承。
//
// ## 这部分比较抽象须要理清晰。##
//
// 函数都有一个prototype属性, prototype属性引用的是该函数的一个对象,也称它为原型对象。
// 对象都有一个constructor属性
//
// 函数本身又是一个对象,我叫这种对象叫函数式对象,所以也有constructor属性,值为 function Function(){ ... },
// (Function这个对象也有constructor属性,就是它本身,
// Function 这个函数的prototype 在 chrome中显示 function Empty(){}, 在IE10中显示 function(){ [native code] })
// 就这样无穷尽也。这里我不是很明白,姑且当作一个称为 “最终函数实例”有能解释下的友人,可以回复我。
//
// 但是对象本身就不一定是函数了,所以对象不一定有prototype属性了。
//
// 范例说明继承问题:
//
function Fu(){} //这是一个函数,我们要把它当作类,要实例化它。 那么它就是一个结构函数。
function Zi(){} //这是子类的结构函数
Fu.prototype.sayHi = function(){log('Hi, ' + this.constructor.name);}; // 给prototype属性引用的原型对象添加了sayHi方法。
// 所以,实例化一个Fu的对象
var f = new Fu(); // 这时发生了什么?调用叫做Fu的结构函数来结构这个对象。
// 现在 f 是一个对象,不是函数式对象,有constructor属性,但是没有prototype属性。
f.sayHi(); // Hi, Fu
// 继承
Zi.prototype = f; // 尝尝Fu.prototype。 这样js自己给Zi的prototype引用就丢失了。也可以直接 new Fu();
Zi.prototype.sayHello = function(){log('Hello, ' + this.constructor.name);};
var z = new Zi();
z.sayHi(); // Hi, Fu
z.sayHello(); // Hello, Fu // 可以看出,其实是给 new Fu() 这个对象添加了属性。
Zi.prototype.constructor = Zi; // 其实是设置了 (new Fu())这个实例的constructor
// 如果没有这句,z的constructor属性就丢失了,就会应用父类对象的constructor,
// 对于 instanceof 运算符没有影响
// z instanceof Zi 返回 true
//
// 查找一个对象的属性,就像作用域链一样,一级一级往高处查询。
//
//
// 一句话:
// js的面向对象,就是 同类实例 同享 (某个一个对象)里的属性和方法,
// 如果没有显示指定这个对象,js就主动给你个对象,叫做 原型对象,new 我类者,我是你们的原型。
// 如果显示指定这个对象,那么就是同享 这个对象 已有的属性和方法,js不给你分配了。就是继承。
// 感觉就是一切环绕对象、属性、方法,引用 展开去。
//
//
// JavaScript中全部对象都是继承自 Object()
// 所以全部对象同享Object对象的属性和方法,如下:
// 1. constructor
// 2. hasOwnProperty() 自己本身的属性才是true
z.hasOwnProperty('sayHello'); // false
f.hasOwnProperty('sayHi'); // false
// 一切 原型对象的属性都是false
z.Hi = 'nihao';
z.hasOwnProperty('Hi'); // true
// 3. isPrototypeOf()
Zi.prototype.isPrototypeOf(z); // true Zi.prototype是z的原型对象吗?
f.isPrototypeOf(z); // true
// 4. propertyIsEnumerable()
// 对象直接定义的属性才可以循环枚举出来, 意思同 hasOwnProperty()
//
// 5. toLocaleString() // locale 意思是场合,现场。就是自己根据情况自定义一个字符串返回
// 6. toString() // 返回字符串,代表调用对象的类型或者值
// 7. valueOf() // 和toString比较像,调用返来的可以不是字符串值
//
// ======================================================================
// 第九章 数组
// ======================================================================
//
// 一些方法:
var arr = Array(3); // new Array(4,2,4), [2, 3, 's', obj]
arr.length == 3;
arr.length = 2; // 根据数字巨细,截断或者增加 undefined元素
arr[0] = 33;
arr[1] = 4;
// arr[] = 1111; // 这个是不允许的,PHP中就这么弄。
arr[2] = 1111;
arr[3] = 222;
//log(arr.toString()); // 调用toString()属性, "33,4,1111,222"
arr.join('!'); // 33!4!1111!222
arr.reverse(); // 倒过来,返回,原数组上操作的
//log(arr); // 已经倒了。
arr.sort(); // 默许按字母排序,原数组上操作的
//log(arr);
arr.sort(function(a, b){
return a-b; // a-b升序, b-a降序
});
//log(arr);
var arr2 = [4,5,null];
//log( arr.concat(null, arr2) ); // 创立并返回合并后的新数组,不去重。null, undefined都可以。
// slice(开始, 结束); 返回片段
//
// splice(a, b, c...); 插入或删除数组的元素,在元素组上操作。返回删除的数组,b=0,返回[];
//
// push(a), pop() // 数组尾部操作, push 返回新数组长度;pop返回删除的元素
//
// unshift(), shift() // 数组头部操作,unshift返回新数组长度;shift 返回删除的元素
//
// 这四个方法可以用来模拟堆栈和队列
// 栈 push pop 后进先出
// 队列 unshift pop 先进先出
//
文章结束给大家分享下程序员的一些笑话语录: 话剧:程序员过沟
本剧内容纯属虚构,如有雷同……HEHE……俺也没办法了。
话说某市街道改建,某某软件公司门口横七竖八挖了几条大沟。一群程序员(SDK程序员赵某,VB程序员钱某,VC程序员孙某,DELPHI程序员李某)下班从公司里出来,看到门前的几条沟,于是各显神通……门前第一条沟也就半米来宽,SDK程序员赵某二话没说,轻轻一跃跳了过去,看到其它人纷纷把随身携带的公文包(类库)横在沟上踩着过沟,不屑地说,这么小一条沟,犯得着小题大做用那个吗?看我多么轻松多么洒脱多么……多么……(众人皆怒目横视之……)
接着第二条沟有点宽度。SDK程序员赵某还是还是一马当先,飞跃而起……不好,还差一点才到……幸好凭着多年的(跳远?编程?)经验,单手抓住沟沿,颤巍巍地爬了上来,嘴里还念念有词“高手就是高手啊,虽然差一点就……不过毕竟……HEHE……跳远是过沟的基础嘛,有基础(SDK)就有一切的说……”(众人作瞠目结舌状……)看到别人跳过去了,可自己又跳不了那么远,只好再想办法了……VB程序员钱某,DELPHI程序员李某打开手提,连上手机,开始上网找可供过沟的控件……VC程序员孙某却不慌不忙,打开公文包,把几块衬板拆了下来,然后三下五除二拼成一个简易木桥……“虽然这几个板子(类)做得不怎么样,不过先把这个项目应付过去,有时间我自己做一个好了……”于是踩着板子过了沟。
这时钱某和李某也分别找到了合适的东东。钱某找到的是“钢丝绳.ocx”,安装简单,使用方便,拉出一头,对孙某说“大虾,顺手拉兄弟一把……”,于是把绳子系在沟两边的绿化树木上,踩着钢丝就过了沟。刚刚站稳就四方作揖,“小生这里有礼了”。这时一戴着黄袖圈的老太太跳了出来,抓住钱某,“破坏绿化树木,罚款XXXX元,交钱,交钱,交钱!”(老人家作双枪老太婆怒视伪军状
……钱某被逼无奈,只好边掏钱,边对着后台叫道“导演,我这可是因公牺牲,不给个烈士称号也得报销”,后台一个臭鸡蛋飞出,“叫什么叫,我这个月的粮饷还不知哪里去领呢,都什么时代了,你不下岗都不错了……”)
李某看着刚刚好不容易从台湾拖回来的“铝条.ZIP”
--------------------------------- 原创文章 By
对象和function
---------------------------------