标签:
今天的JavaScript拥有了闭包、匿名函数、元编程等特性。它简单又复杂!
组成要素:
文档模式
严格模式
顶部加
关键字和保留字
关键字:
保留字:
函数内部的变量如何当作全局变量使用:(曾经要用到这个知识当时找不到答案)但是不推荐。
typeof操作符
前置 与 后置的区别:
==(数值)与===(数值+类型)的区别
不允许用with 所有变量必须声明, 赋值给为声明的变量报错,而不是隐式创建全局变量。 eval中的代码不能创建eval所在作用域下的变量、函数。而是为eval单独创建一个作用域,并在eval返回时丢弃。 函数中得特殊对象arguments是静态副本,而不像非严格模式那样,修改arguments或修改参数变量会相互影响。 删除configurable=false的属性时报错,而不是忽略 禁止八进制字面量,如010 (八进制的8) eval, arguments变为关键字,不可作为变量名、函数名等 一般函数调用时(不是对象的方法调用,也不使用apply/call/bind等修改this)this指向null,而不是全局对象。 若使用apply/call,当传入null或undefined时,this将指向null或undefined,而不是全局对象。 试图修改不可写属性(writable=false),在不可扩展的对象上添加属性时报TypeError,而不是忽略。 arguments.caller, arguments.callee被禁用
typeof 100 === “number” typeof true === “boolean” typeof function () {} === “function” typeof(undefined) ) === “undefined”
typeof(new Object() ) === “object” typeof( [1, 2] ) === “object” typeof(NaN ) === “number” typeof(null) === “object”
Object.prototype.toString.apply([]) === “[object Array]”;
Object.prototype.toString.apply(function(){})=== “[object Function]”;
Object.prototype.toString.apply(null)=== “[object Null]”;
Object.prototype.toString.apply(undefined) === “[object Undefined]”
类型检测小结:
typeof 适合基本类型及function检测,遇到null失效。
[[Class]] 通过{}.toString拿到,适合内置对象和基元类型,遇到null和undefined失效(IE678等返回[object Object])。
instanceof 适合自定义对象,也可以用来检测原生对象,在不同iframe和window间检测时失效。
参数是按值传递的,不是按引用传递。
JavaScript没有块级作用域(如下例子)
JavaScript是一门具有自动垃圾收集机制的编程语言。
“标记清除”是目前主流的垃圾收集算法。还有种“引用计数”(IE中访问非原生JS对象会导致问题)
创建object类型的方式
一种是 另一种是(对象字面量)常用:(注意格式)
对象字面量也是函数传递大量参数的首选方式
1 function displayInfo(args){ 2 var output = ""; 3 if (typeof args.name == "string") { 4 output += "Name: " + args.name +"\n"; 5 } 6 if (typeof args.age == "number") { 7 output += "Age: " + args.age +"\n"; 8 } 9 10 alert(output); 11 } 12 13 displayInfo({ 14 name:"Muyunyun", 15 age:29 16 }); 17 18 displayInfo({ 19 name:"wky" 20 });
属性操作:
var obj = {x : 1}; obj.y; // undefined var yz = obj.y.z; // TypeError: Cannot read property ‘z‘ of undefined obj.y.z = 2; // TypeError: Cannot set property ‘z‘ of undefined 可以这样写: var yz; if (obj.y) { yz = obj.y.z; } 或者 var yz = obj && obj.y && obj.y.z;
var globalVal = 1; delete globalVal; // false (function() { var localVal = 1; return delete localVal; }()); // false ---------------------------------- function fd() {} delete fd; // false (function() { function fd() {}; return delete fd; }()); // false ------------------------------------ ohNo = 1; window.ohNo; // 1 delete ohNo; // true
1 var cat = new Object; 2 cat.legs = 4; 3 cat.name = "Kitty"; 4 5 ‘legs‘ in cat; // true 6 ‘abc‘ in cat; // false 7 "toString" in cat; // true, inherited property!!! 8 9 10 cat.hasOwnProperty(‘legs‘); // true 11 cat.hasOwnProperty(‘toString‘); // false 12 13 //枚举 14 cat.propertyIsEnumerable(‘legs‘); // true 15 cat.propertyIsEnumerable(‘toString‘); // false 16 17 18 Object.defineProperty(cat, ‘price‘, {enumerable : false, value : 1000}); 19 cat.propertyIsEnumerable(‘price‘); // false 20 cat.hasOwnProperty(‘price‘); // true 21 22 23 if (cat && cat.legs) { 24 cat.legs *= 2; 25 } 26 27 28 if (cat.legs != undefined) { 29 // !== undefined, or, !== null 30 } 31 32 33 if (cat.legs !== undefined) { 34 // only if cat.legs is not undefined 35 }
var o = {x : 1, y : 2, z : 3}; ‘toString‘ in o; // true o.propertyIsEnumerable(‘toString‘); // false var key; for (key in o) { console.log(key); // x, y, z } var obj = Object.create(o); obj.a = 4; var key; for (key in obj) { console.log(key); // a, x, y, z } var obj = Object.create(o); obj.a = 4; var key; for (key in obj) { if (obj.hasOwnProperty(key)) { console.log(key); // a } }
getter/setter方法
var man = { weibo : ‘@muyunyun‘, $age : null, get age() { if (this.$age == undefined) { //null和undefined都包括进去了 return new Date().getFullYear() - 1995; } else { return this.$age; } }, set age(val) { val = +val; if (!isNaN(val) && val > 0 && val < 150) { this.$age = +val; } else { throw new Error(‘Incorrect val = ‘ + val); } } } console.log(man.age); // 22 //执行get man.age = 100; console.log(man.age); // 100; //执行set man.age = ‘abc‘; // error:Incorrect val = NaN
创建array类型的方式
var colors = new Array(20);
var colors = new Array("red", "blue", "green");
var colors = ["red", "blue", "green"];(数组字面量)
检测数组:
单一全局执行环境 网页中多个框架
转换方法:所有对象都有toLocaleString()、toString()、valueOf()方法
join方法:
栈方法:(后进先出)
队列方法:(先进先出) shift() 还有个对应的unshuit()方法:从最前面推入
重排序方法:reverse(): sort():
要正续排的话如下:
var values = [0, 1, 5, 10, 15]; values.sort(compare); alert(values); function compare(values1,values2){ return values1 - values2; }
操作方法:
concat()slice():参数包括头不包括尾
splice():能实现删除、插入、替换
位置方法:indexOf() lastIndexOf() : 两个参数表示要查找的项和表示起点位置的索引。
迭代方法:
every() some()
filter() map()
forEach():没有返回值
归并方法:
reduce() reduceRight():与reduce()相反
Data类型
Data.parse()
等价
Data.UTC()
RegExp类型
RegExp实例属性:
exec():接收一个参数日狗返回第一个匹配项信息的数组;
test(): 可以验证输入的文本与模式是否匹配 接收一个字符串参数,返回true或false;
var text = "000-00-0000"; var pattern = /\d{3}-\d{2}-\d{4}/; if (pattern.test(text)) { alert("The pattern was matched"); }
、
RegExp构造函数属性:
==
Function类型
作为值的函数
function callSomeFunction(someFunction, someArgument){ return someFunction(someArgument); //作为值的函数 } function getGreeting(name){ return "Hello, " + name; } var result2 = callSomeFunction(getGreeting, "Muyunyun"); alert(result2); function add10(age){ return "10years later my age is " + (age + 10); } var result1 = callSomeFunction(add10, 22); alert(result1);
函数中返回另一个函数
1 function createComparisonFunction(propertyName){ 2 return function(object1,object2){ 3 var value1 = object1[propertyName]; 4 var value2 = object2[propertyName]; 5 if(value1 < value2){ 6 return -1; 7 } else if (value1 > value2){ 8 return 1; 9 }else{ 10 return 0; 11 } 12 } 13 } 14 var data = [{name:"Zachary", age: 28},{name: "Nicholas", age: 29}]; 15 data.sort(createComparisonFunction("name")); 16 alert(data[0].name); //Nicholas 17 18 data.sort(createComparisonFunction("age")); 19 alert(data[0].name); //Zachary
函数内部属性
非常经典的阶层函数(arguments.callee消除耦合) callee:该属性是一个指针,指向拥有这个arguments对象的函数。
1 function factorial(num){ 2 if(num <= 1){ 3 return 1; 4 } else{ 5 return num * factorial(num-1); //产生耦合 6 } 7 } 8 var trueFactorial = factorial; 9 10 factorial = function(){ 11 return 0; 12 }; 13 alert(trueFactorial(5)); //这时候就是0 14 alert(factorial(5)); //0 15 16 17 18 19 20 function factorial(num){ 21 if(num <= 1){ 22 return 1; 23 } else{ 24 return num * arguments.callee(num-1); 25 } 26 } 27 28 var trueFactorial = factorial; 29 30 factorial = function(){ 31 return 0; 32 }; 33 alert(trueFactorial(5)); //120 34 alert(factorial(5)); //0
函数的名字仅仅是一个包含指针的变量而已。
this
window.color = "red"; var o = { color: "blue"}; function sayColor(){ alert(this.color); } sayColor(); o.sayColor = sayColor; o.sayColor();
caller :这个属性中保存着调用当前函数的函数的引用。
function outer(){ inner(); } function inner(){ alert(inner.caller); } outer(); function outer(){ inner(); } function inner(){ alert(arguments.callee.caller); //更松散的耦合 } outer(); //输出function outer(){inner();}
apply()方法接收两个参数,一个是在其中运行函数的作用域,另一个是参数数组
call()方法与apply()相同,只是接收参数方式不同
call()与apply()真正强大的地方是能扩充函数赖以运行的作用域
本来需要 o.sayColor() = sayColor; o.sayColor() 这样子调用的
bind() :这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值
Number类型
toFixed() toExponential() toPrecision()
String类型
1.字符方法:charAt() 、 charCodeAt()、 stringValue[]
2.字符串操作方法:concat():通常直接用+号; slice()、substr()、substring()
3.字符串位置方法: indexOf()、lastIndexOf()
4.trim():删除空格
5.字符串大小写转换方法:toLowerCase()、toLocaleLowerCase()、toUpperCase()、toLocaleUpperCase()
6.字符串的模式匹配方法:match() 、search() 、replace()、split()
7.localeCompare()
单体内置对象
1.eval()
Math对象
1.min、max
2.舍入方法
Math.ceil():向上舍入; Math.floor():向下舍入; Math.round():标准舍入
3.random()
1.工厂模式 2.构造函数模式 3.原型模式 4.组合使用构造函数模式与原型模式(构造函数用于定义实例属性,原型模式用于定义方法和共享的属性) 5.动态原型模式
继承
原型链
1 function SuperType(){ 2 this.property = true; 3 } 4 SuperType.prototype.getSuperValue = function(){ 5 return this.property; 6 }; 7 8 function SubType(){ 9 this.subproperty = false; 10 } 11 12 SubType.prototype = new SuperType(); /*继承了SuperType*/ 13 14 SubType.prototype.getSubValue = function(){ 15 return this.subproperty; 16 }; 17 18 var instance = new SubType(); 19 alert(instance.getSuperValue());
组合继承:使用原型链实现对原型属性和方法的继承,通过构造函数实现对实例属性的继承。(最常用的继承模式)
1 function SuperType(name){ 2 this.name = name; 3 this.colors = {"red","blue","green"}; 4 } 5 6 SuperType.prototype.sayName = function(){ 7 alert(this.name); 8 } 9 10 function SubType(name, age){ 11 //继承属性 12 SuperType.call(this, name); 13 this.age = age; 14 } 15 16 //继承方法 17 SubType.prototype = new SuperType(); 18 SubType.prototype.sayAge = function(){ 19 alert(this.age); 20 }; 21 22 var instance1 = new SubType("Nicholas", 29); 23 instance1.colors.push("black"); 24 alert(instance1.colors); //"red,blue,green,black" 25 instance1.sayName(); //"Nichilas" 26 instance1.sayAge(); //29
寄生组合式继承:最理想的继承方式
递归
arguments.callee指向正在执行的函数的指针
1 //正确 2 function factorial(num){ 3 if(num <= 1){ 4 return 1; 5 }else{ 6 return num * arguments.callee(num-1); 7 } 8 } 9 10 var anotherFactorial = factorial; 11 factorial = null; 12 alert(anotherFactorial(4)); 13 14 15 16 //错误 17 function factorial(num){ 18 if(num <= 1){ 19 return 1; 20 }else{ 21 return num * factorial(num-1); 22 } 23 } 24 25 var anotherFactorial = factorial; 26 factorial = null; 27 alert(anotherFactorial(4));
闭包:是指有权访问另一个函数作用域中的变量的函数。
模仿块级作用域:
(function(){ //这里是块级作用域 })();
实践比较重要。。。未完待续。。。
标签:
原文地址:http://www.cnblogs.com/MuYunyun/p/5702439.html