學習【JavaScript權威指南】(一)
不看不得了,一看嚇一跳。。。好多簡單的東西都不懂的,寫個 $(function(){ } ); 還需要查詢下才記起來。。。
var book = { topic: "Javascript", fat: true //true, false布林值 null為空 undefined為未定義 } book.author = "why-su"; //通過賦值建立一個新屬性 book.content = {}; //{} 是一個空物件 book.plus = function(){ //定義一個方法 return this.topic; //this對自己的引用 } book.plus(); //執行方法
關於prototype的理解:https://www.cnblogs.com/loveyoume/p/6112044.html ( prototype 這個屬性是函式特有的屬性 ,而且是函式的原型物件。對原型物件增加的屬性及其方法,new例項化 之後的物件都能繼承。)
function Point(x,y) { this.x = x; this.y = y; } Point.prototype.z = function () { return Math.sqrt(this.x * this.x + this.y*this.y); }; var p = new Point(3,4); alert(p.z()); //結果是 5
隱藏,但保留空間 this.style.visibility = "hidden"
隱藏,不保留空間 this.style.display = "none"
Math的函式多多少少也要給我記住一些:
Math.pow(2,53); //2的53次方
Math.sqrt(4); //4的平方根
Math.pow(8,1/3); //8的立方根
Math.ceil(.3); //向上取整
Math.floor(.3); //向下取整
Math.ceil(.3); //四捨五入
無窮大 Infinity 負無窮大 -Infinity 負零 -0
被零整除在JavaScript不報錯,只是返回無窮大Infinity。
零除零是沒有意義的,返回 NaN (非數字值), NaN和任何數都不相等,包括自身,也就是無法使用 x == NaN來判斷x變數是否是NaN, 而要使用 x!=x 來判斷,當且僅當 x 為NaN的時候,表示式才為 true
var y = "one\
long\
line"; //一行顯示的話要在每行末尾加上 \
var y = "one\long\line"; //如果 找不到\l這個轉義字元的話,\會被忽略
var z = "0123456789";
z.charAt(0); //第0位的字元
z.substring(2,5); //索引第2位到第5位 擷取
z.slice(2,5); //和substring功能一樣
z.slice(-3); //擷取最後三位
z.indexOf("1"); // 字元1 首次出現的位置
z.indexOf("1",3); //字元1 在 索引3位置之後 首次出現的位置
z.lastIndexOf("1"); //字元1 最後一次出現的位置
注意,字串是固定不變的,類似replace(), toUppserCase() 都返回新字串,原字串本身是不變的。
if(o){
//o不是false或任何假值(比如null或undefined)
}
if(o != null){
//o不是 null
}
undefined 是 預定義的全域性變數(和null不一樣,不是關鍵字),它的值就是 未定義,二者都表示值得空缺
null == undefined //true
null === undefined //false
=== 嚴格相等,如果兩個值都是null或者都是undefined,則它們不相等
兩個物件/陣列 是永不相等的,即使含有相同的屬性
型別轉換
"2" * "5" //結果是10,兩個字串均轉換為10
"2" + "5" //結果是"25", + 連線字串
var n = 1 - "x"; //x無法轉換為數字,得到的值為 NaN
n + "Object"; //NaN轉為字串 "NaN",得到的值是 "NaNObject"
"1" + 2 //結果是"12",數字轉換為字串後相加
1 + {} //結果是 "1[object object]"
true + true //結果是2,布林值轉換為數字後相加
2 +null //結果是2, null轉換為0後相加
2 + undefined //結果是NaN, undefined轉換為NaN後相加
區別: == 在判斷前做了 型別轉換, === 未轉換型別
parseInt() parseFloat() 全域性函式,不屬於任何類的方法
所有物件繼承了2個轉換方法:1,toString() 2,valueOf()
JavaScript中物件到字串的轉換:先找 toString(),再找 valueOf(), 如果無法獲得一個原始值,則拋型別轉換異常
物件到數字的轉換:先找valueOf()再找 toString(),否則拋異常
var d; // 未賦值之前,值是 undefined
e; //報錯,e is not defined
var arr = [0,,,,4]; //包含5個元素,其中三個元素是 undefined
var a1 = []; //空陣列
var a2 = {}; //空物件
var o = {x:1, y:{z:3}}; //可以使用 o.y.z 或 o["y"]["z"]取值
所有無法轉換為數字的運算元都會轉為 NaN
new Object()
new Object //建立物件,如果不需要傳任何引數,括號可以省略
JavaScript的所有值不是真值就是假值
11 < 3 //false 數字比較
"11" < "3" //true, 字串比較
"11" < 3 //false, "11"轉換為數字再進行數字比較
"one" < 3 //false,數字比較,"one"轉換為NaN, >,<,>=,<=只要有一個為NaN,結果都為false
關於eval() : https://blog.csdn.net/u011897392/article/details/58139194
typeof null //為"object"
typeof undefined //為"undefined"
typeof true或false //為"boolean"
typeof 任意數字或NaN // 為"number"
typeof 字串 //為"string"
typrof 函式 //為"function"
in
//屬性
var o = {x: 1, y: 2};
"x" in o; //true, 物件o有屬性x
"toString" in o; //true 物件繼承了toString()方法
var data = [7,8,9];
"0" in data; //true 如果是陣列,因為是屬性,data[0]為7
0 in data; //true, 數字轉換為字串
3 in data; //false, 沒有索引為3的元素
還可以這樣用哈哈 (o゚▽゚)o
<a href="javascript:void(alert('要死要死'));">連結</a>
var o = new Object(); //建立空物件,和var o = {} 一樣
var o = new Array();
var o = new RegExp("js");
var a= {a0: 0,a1: 1, a2: 2, a3: 3};
//我們知道兩種寫法 a.a0, a["a0"] 都可以獲得值,但以下這種情況只能用a[" "]的寫法
var addr;
for(var i = 0; i < 4; i++){
addr += a["a"+i] + "\n";
}
$(function () {
var o = {x: 1,y: 2}; //o 從 Object.prototype 原型,繼承物件的方法
var a = inherit(o); // a 繼承 o 和 Object.prototype
console.log(a.y); //2
a.x = 2; //覆蓋繼承來的屬性
console.log(o.x); //1 原來物件o的屬性沒受到影響
console.log(a.x); //2
a.z = 3; //屬性賦值要麼失敗,要麼建立一個屬性
console.log(a.z); //3
//如果查不到該屬性
console.log(o.w); //返回undefined
console.log(o.w.length); //因為null或undefined是沒有屬性的,這裡會報錯
//簡練的防止報錯的常用方法
var len = o && o.w && o.w.length;
})
function inherit(p){
if(p == null) throw TypeError();
if(Object.create){
return Object.create(p);
}
var t = typeof p;
if(t !== "object" && t !== "function") throw TypeError();
function f() {};
f.prototype = p; //屬性賦值要麼失敗,要麼建立一個屬性
return new f();
}
var o = {x: 1}
"x" in o; //true
"y" in o; //false
"toString" in o; //true o繼承toString屬性
//除了in之外,可以使用 !== (!== 可區分null和undefined,注意不是 !=)
o.x !== undefined //true
o.y !== undefined //false
o.toString !== undefined //true o繼承toString屬性
o.hasOwnProperty("x"); //true
o.hasOwnProperty("y"); //false
o.hasOwnProperty("toString"); //false, 不是物件的自有屬性
//跳過繼承來的屬性
for(p in o){
if(!o.hasOwnProperty(p)) continue;
}
getter 和 setter
var p = {
$n: 1, //$符號暗示這個屬性是一個私有屬性
x: 3.0,
y: 4.0,
get r() { return Math.sqrt(this.x * this.x + this.y * this.y);},
set r(newValue){
var oldValue = Math.sqrt(this.x * this.x + this.y * this.y);
var ratio = newValue/oldValue;
this.x *= ratio;
this.y *= ratio;
}
};
console.log(p.r); //5
p.r = 50;
console.log(p.x +","+p.y); //30,40
序列化物件 serialization是指將物件的狀態轉換為字串,也可將字串還原為物件。
JSON.stringify() 序列化,JSON.parse() 還原JavaScript物件
陣列:
var a = [];
var b = new Array();
var c = new Array(10); //只寫一個引數的話,建立的陣列長度是10,但是沒有任何元素
var d = new Array(5,4,3,2,1,"test","why"); //長度是7
var e = [5,4,3,2,1,"test","why"]; //長度是7
//可以使用 負數或非整數來索引陣列。這種情況下,數值將轉換為“字串”,將“字串”作為屬性名來用
a[-1.23] = true; //建立名為"-1.23"的屬性
a[1.00] //和 a[1]一樣
a["1000"] //和a[1000]一樣,如果不存在,則返回 undefined
a[1000] = 1; //賦值新增一個新元素,並且設定length為1001
//JavaScript陣列不存在“越界”錯誤
//稀疏陣列
var a1 = [,,]; //長度是2,但沒有元素
var a2 = [undefined,undefined];
a1[0] //undefined
a2[0] //undefined
0 in a1 //false, 在索引0處沒有元素
0 in a2; //true, 在索引0處有元素
a = [1,2,3,4,5]
a.length = 0; //刪除所有的元素,a為[]
a.length = 5; //長度為5,但沒有任何元素,像new Array(5);
//可以設定length為只讀
Object.defineProperty(a,"length",{writable: false});
//此時再使用 a.length = 0;就不會改變了。
//新增元素
var a = [];
a[5] = "zero";
//或者使用 push
a.push("zerp");
a.push("zero","one"); //新增2個元素
//刪除元素
var a = [1,2,3,4,5];
delete a[1]; //在索引1位置不再有元素
console.log(1 in a); //false 索引1位置未在陣列中定義
console.log(a.length); //5 delete操作不影響陣列長度
a.pop(); //刪除陣列的最後一個元素,長度改變
a.shift(); //刪除陣列的第一個元素,長度改變
//for迴圈
var a = [1,2,3,4,5];
for(var i = 0; i < a.length; i++){
if(!a[i]) continue; //跳過null,undefined,不存在的元素
if(a[!] === undefined) continue; //跳過undefined
if(!(i in a)) continue; //跳過不存在的元素
}
//in 會跳過不存在的索引不會被遍歷到
for(var i in a){
if(!a.hasOwnProperty(i)) continue; //跳過繼承的屬性
console.log(a[index]);
}
//forEach()方法,按照索引順序遍歷陣列
a.forEach(function(value,index){
console.log(value); //value是值,index是索引
});
//join方法將陣列所有元素轉為字串
var a = [1,2,3,4,5];
console.log(a.join()); //1,2,3,4,5 預設用逗號
console.log(a.join("")); //12345
console.log(a.join(" ")); //1 2 3 4 5
a.reverse(); //陣列元素顛倒(在原陣列的基礎上),a變為 [5,4,3,2,1]
//sort排序
var b = ["scd","Ad","por","Fased","gerg","da"];
console.log(b.sort()); //按照字母表順序排序,區分大小寫
console.log(b.sort(function (a,b) { //自定義排序規則,不區分大小寫,負數排前面
a = a.toLowerCase();
b = b.toLowerCase();
if(a < b) return -1;
if(a > b) return 1;
return 0;
}));
//slice擷取陣列,包左不包右, 不會修改原陣列
var a = [0,1,2,3,4,5];
console.log(a.slice(0,3)); //[0,1,2]
console.log(a.slice(3)); //[3,4,5] 索引3後的內容
console.log(a.slice(0,-1)); //[0,1,2,3,4] -1表示倒數第一個
console.log(a.slice(-3,-1)); //[3,4] -3表示倒數第三個
//splice()會改變原陣列,第一個引數指插入/刪除的起始位置,第二個引數指定 刪除的元素個數,
// 如果省略第二個元素,則從起始點位置後的所有元素都被刪除,返回被刪除的陣列。
var a = [0,1,2,3,4,5,6];
console.log(a.splice(5)); //[5,6]
console.log(a); //[0,1,2,3,4]
console.log(a.splice(1,3)); //[1,2,3]
console.log(a); //[0,4]
//從第三個引數開始,指定了要加入的元素
console.log(a.splice(1,0,1,2,3)); //[]
console.log(a); //[0,1,2,3,4]
//every()是指所有元素都必須滿足要求才返回true, some()是隻要有一個元素滿足要求就返回true
var a = [0,1,2,3,4,5,6];
console.log(a.every(function (t) { return t<10; })); //true 所有元素都小於10
console.log(a.some(function (t) { return t % 2 === 0; })); //true 至少存在一個元素能被2整除
//reduce按照 從左到右的順序,第二個引數是初始值
var a = [1,2,3];
//初始值是0,按照從左到右順序: 0 + 1 + 2 + 3 = 6
var sum = a.reduce(function (x, y) { return x + y; },0);
//初始值是1,按照從左到右順序: 1*1*2*3 = 6
var product = a.reduce(function (x, y) { return x * y; },1);
//初始值是0,按照從左到右順序判讀,結果3
var max = a.reduce(function (x, y) { return x > y ? x : y; },0);
//reduceRight() 方法與 reduce()相反,從右至左
JavaScript,函式可以巢狀在其它函式裡面
當呼叫函式的時候傳入的實參比函式宣告時指定的形參個數要少,剩下的形參都將設定為undefined
arguments是指向實參物件的引用,使用下標可以訪問傳入函式的引數
//傳入引數數量不定
function max(){
var max = Number.NEGATIVE_INFINITY; //負無窮大
for(var i = 0; i < arguments.length; i++){
if(arguments[i] > max) max = arguments[i];
}
return max;
}
呼叫 max(-34,-9,-12,-13,-48) 得到最大的 -9
第8章【函式】看的有點暈
//以下建立了10個閉包,但這些閉包都是在同一個函式呼叫中定義的,因此它們可以共享變數i
function constfuncs(){
var funcs = [];
for(var i = 0; i < 10; i++){
funcs[i] = functio(){ return i;};
}
return funcs;
}
var funcs = constfuncs();
funcs[5](); //結果是10,而不是5,這10個閉包的返回值都是10,因為共享了變數i
//需要這樣寫
function constfunc(i){
return function(){return i;}
}
var funcs = [];
for(var i = 0; i < 10; i++){
funcs[i] = constfunc(i);
}
funcs[5](); //結果是5
function check(args){
var actual = args.length; //實際傳參個數
var expected = args.callee.length; //期望的傳參個數
if(actual != expected)
throw Error("Expected " + expected + "args; got " + actual);
}
function f(x,y,z){
check(arguments);
return x + y + z;
}
f(1)報錯 f(1,2)報錯 f(1,2,3)正確返回6