基础
- JavaScript中的全局函数-数值型函数
- JavaScript中的全局函数
- JavaScript中的特殊形式函数-匿名函数的应用
- JavaScript中的对象-如何自定义对象
- JavaScript中的对象-对象的结构
- JavaScript中的对象-属性的特性
- JavaScript中的对象-属性特性描述
- JavaScript中的对象-对象的特性
- JavaScript中的内建对象-Date对象
- JavaScript中的内建对象-RegExp对象
- JavaScript中的内建对象-Error对象
- JavaScript中的数组对象
- JavaScript中的事件简介
- DOM2级事件绑定和移除
- JavaScript中的事件对象及兼容性
- JavaScript中的兼容性问题和onload事件
- JavaScript表单验证
进阶
JavaScript中的特殊形式函数
<eg1>
function a(param){
function b(param1){
return param1 + 10;
}
return '在a函数体内调用b函数结果' + b(param);
}
document.write(a(5));
//输出结果:
//在a函数体内调用b函数结果15
<eg2>
function a(param){
var b = function(param1){
return param1 + 10;
}
return '在a函数体内调用b的结果:' + b(param);
}
document.write(a(5));
//输出结果:
//在a函数体内调用b的结果:15
<eg3>
//返回函数的函数
function a(){
alert('aaa');
return function(){
alert('bbb');
};
}
//调用方式一:
var b = a();
b();
//调用方式二:
a()();
//输出结果:
//弹框显示aaa,再弹框显示bbb
<eg4>
//重写自己的函数
function a(){
alert('aaa');
a = function(){
alert('bbb');
}
}
a();
a();
//输出结果:
//第一次调用,显示alert('aaa').第二次或之后调用,显示 alert('bbb')
<eg5>
//函数的自调用
var a = function(){
function setUp(){
var setup = 'doSomeThing';
}
function doWhat(){
alert('要执行的操作');
}
setUp();
return doWhat();
}();
a();
//输出的结果是:
//弹框:'要执行的操作'
//分析:
//var a = function(){}() ; 这种格式为自调用
<eg6>
//创建函数方式一
var func = new Function('a','b','return a+b');
alert(func(3,4)); //弹框显示7
//创建函数方式二
var func2 = function(a,b){return a+b}; //弹框显示7
alert(func2(3,4));
//输出结果:
//弹框显示7
//分析:创建函数方式一和方式二是等价的。方式一是通过JS内置函数构造器创建的
JavaScript中的闭包
闭包理解:
突破自身函数作用域的限制,把函数内的局部变量共享到外部。
闭包缺点:
1.闭包会使到函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄漏。尽量在退出函数之前,将不使用的局部变量全部删除。
2.闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当做对象使用,把闭包当做它的公用使用方法,把内部变量当做它的私有属性,这时一定要小心,不要随便改变父函数内部变量的值。
//突破闭包自身作用域限制,从而达到全局共享
function closure() {
var a = 'return closure';
return function(){
return a;
}
}
alert(closure()());
//输出结果:
//弹框显示'return closure'
//分析
//现想要 a = 'return closure' 全局共享。但 a 只是closure()函数的局部变量,通过closure() 返回 变量就可以达到目的。这种方法叫闭包
function closure(param){
var n = function(){
return param;
}
param++;
return n;
}
alert(closure(5)());
//输出结果:
//弹框显示6.
JavaScript中的闭包应用
function f1(){
var n = 1;
test = function(){
n+=1;
}
function f2(){
alert(n);
}
return f2;
}
var res = f1();
alert(res());
//输出结果:
//先弹框显示1,再弹框显示undefined
var setVaule,getValue;
(function(){
var n = 0;
setVaule = function(x){
n = x;
}
getValue = function(){
return n;
}
})()
alert(getValue());
setVaule(5);
alert(getValue());
//输出结果:
//先弹框显示0,再弹框显示5.
function test(x){
var i = 0;
return function(){
return x[i++];
}
}
var next = test(['a','b','c','d'])
alert(next());
alert(next());
alert(next());
alert(next());
//输出结果:
//先弹框显示a,再弹框显示b,再弹框显示c,再弹框显示d
function f(){
var a=[];
var i;
for(i=0;i<3;i++){
a[i] = function(){
return i;
}
}
return a;
}
var test = f();
alert(test[0]());
alert(test[0]());
alert(test[0]());
//输出结果:
//先弹框显示3,再弹框显示3,再弹框显示3
function f(){
var a=[];
var i;
for(i=0;i<3;i++){
a[i] = (function(x){
return function(){
return x;
}
})(i);//函数自调用
}
return a;
}
var test = f();
alert(test[0]());
alert(test[1]());
alert(test[2]());
//输出结果:
//先弹框显示0,再弹框显示1,再弹框显示2
function f(){
function test(x){
return function(){
return x;
}
}
var a = [];
var i;
for (i=0;i<3;i++) {
a[i] = test(i);
}
return a;
}
var test = f();
alert(test[0]());
alert(test[1]());
alert(test[2]());
//输出结果:
//先弹框显示0,再弹框显示1,再弹框显示2
JavaScript中的对象-对象的扩展性
//是否可以往该对象添加新的属性
(1)所有内置对象和自定义对象都是显示可扩展的,宿主对象的可扩展性有JavaScript引擎定义的。
(2)可以通过Object.preventExtensions()将对象设置为不可扩展的,而且不能再转换成可扩展的了,可以通过Object.isExtensible()检测对象是否可扩展的。
(3)preventExtensions()只影响到对象本身的可扩展性,如果给一个不可扩展的对象的原型添加属性,这个不可扩展的对象同样会继承这些新的属性
(4)可扩展性的目的是将对象锁定,防止外界干扰,通常和对象的属性的可配置行与可写性配合使用
(5)Object.seal()和Object.preventExtensions()类似,除了能够将对象设置为不可扩展的,还可以将对象的所有自身属性都设置为不可配置的。也就是说不能给这个对象添加新的属性,而且它已有的属性也不能删除或配置,不过他已有的可写属性依然可以设置。可以通过Object.isSealed()检测对象是否封闭
(6)Object.freeze()将更严格地锁定对象-冻结(frozen).除了对象设置为不可扩展的和将其属性设置为不可配置的之外,还可以将它自身的所有数据属性设置为只读(如果对象的存储属性具有setter方法,存取器属性将不受影响,仍然可以通过给属性赋值调用他们)。可以使用Object.isFroze()来检测对象是否冻结
var obj = {};
//检测对象是否可扩展
console.log(Object.isExtensible(obj)); //true
var d = new Date();
console.log(Object.isExtensible(d)); //true
obj.x = 10;
console.log(obj.x); //10
//通过preventExtension() 将对象变为不可扩展的
obj1 = Object.preventExtensions(obj);
console.log(obj1===obj); //true
console.log(Object.isExtensible(obj1)); //false
console.log(Object.isExtensible(obj)); //false
//为一个不可扩展的对象添加属性
obj1.y = 20;
console.log(obj1.y); //undefined
Object.defineProperty(obj1,'z',{value:1});//为对象定义一个属性。报错:Uncaught TypeError: Cannot define property z, object is not extensible
var obj = {
x:10,
y:20,
name:'samuelandkevin'
};
obj.age = 22;//添加新属性age
delete obj.x;//删除已有的属性x
var objSeal = Object.seal(obj); //封闭对象
console.log(objSeal===obj); //true
console.log(Object.isExtensible(objSeal));//false , 封闭对象不可扩展
objSeal.y = 55; //封闭对象试图修改已有属性y的值
console.log(objSeal.y); //55. 封闭对象可以修改已有属性
Object.defineProperty(obj,'name',{ //封闭对象试图将已有属性name修改它的获取方法
get: function(){
return 'this is a test';
}
}); //报错:Uncaught TypeError: Cannot redefine property: name at Function.defineProperty (<anonymous>)
objSeal.z = 77; //封闭对象试图添加属性z
console.log(objSeal.z); //undefined,系统没有报错。
delete objSeal.name; //试图删除封闭对象的已有属性
console.log(objSeal.name); //samuelandkevin,证明不可以删除封闭对象的已有属性
console.log(Object.isSealed(objSeal));//true ,Object.isSealed()判断对象是否被封闭
Object.defineProperty(objSeal,'name',{value:'newName'});
console.log(objSeal.name); //newName
//打印obj对象的'name'属性 。注意configurable为false
console.log(Object.getOwnPropertyDescriptor(obj,'name'));//Object {value: "newName", writable: true, enumerable: true, configurable: false}
var obj = {
prop:function(){},
foo:'samuelandkevin'
};//定义一个对象,prop为方法,foo为属性
obj.test = 'this is a test';
delete obj.prop;
var objFreeze = Object.freeze(obj);//冻结对象
console.log(objFreeze===obj); //true
console.log(Object.isFrozen(objFreeze)); //true,(对象是否被冻结)
objFreeze.x = 1; //试图往已冻结对象中添加属性
console.log(objFreeze.x); //undefined
console.log(objFreeze.foo); //samuelandkevin
objFreeze.foo = 'newValue'; //试图修改已冻结对象里的属性
console.log(objFreeze.foo); //samuelandkevin,(修改失败,因为对象已冻结)
//浅冻结
var obj2 = {
internal:{}//internal为一个对象
};
Object.freeze(obj2);//冻结
obj2.internal.x = 1;
console.log(obj2.internal.x); //1,(修改成功,因为对象是浅冻结)
//深冻结
function deepFreeze(obj){
var prop,propkey;
Object.freeze(obj);
for(propkey in obj){
prop = obj[propkey];
if(!obj.hasOwnProperty(propkey)||!(typeof prop === 'object')||Object.isFrozen(prop)){
continue;
}
deepFreeze(prop);
}
}
var obj3= {
internal:{}//internal为一个对象
};
deepFreeze(obj3);//冻结
obj3.internal.x = 1;
console.log(obj3.internal.x); //undefined,(修改失败,因为对象是深冻结)
//默认对象是可扩展的,也就是非冻结的
console.log(Object.isFrozen()); //false,非冻结
//一个不可扩展的对象同时也是一个冻结的对象
var obj = Object.preventExtensions({}); //不可扩展的对象obj
console.log(Object.isFrozen(obj)); //true
//一个非空对象默认是非冻结的
var obj1 = {x:1};
console.log(Object.isFrozen(obj1)); //false,非冻结
Object.preventExtensions(obj1);
console.log(Object.isFrozen(obj1)); //false,非冻结
delete obj1.x;
console.log(Object.isFrozen(obj1)); //true (没有任何元素的对象,空对象是冻结了)
//一个不可扩展的对象,拥有一个不可写但可配置的属性,仍然是非冻结的
var obj2={x:1};
Object.preventExtensions(obj2); //不可扩展
Object.defineProperty(obj2,'x',{writable:false}); //不可写
console.log(Object.isFrozen(obj2)); //fasle
Object.defineProperty(obj2,'x',{configurable:false});//不可配置
console.log(Object.isFrozen(obj2)); //true. 冻结了
//如果一个不可扩展的对象,拥有一个不可配置但可写的属性,是非冻结的
var obj3 = {x:1};
Object.preventExtensions(obj3); //不可扩展
Object.defineProperty(obj3,'x',{configurable:false}); //不可配置
console.log(Object.isFrozen(obj3)); //false,非冻结的
Object.defineProperty(obj3,'x',{writable:false}); //不可写
console.log(Object.isFrozen(obj3)); //true,冻结的
//如果一个不可扩展的对象拥有一个访问器属性,它也是非冻结的
var obj4 = {
get test(){
return 1;
}//拥有一个访问器属性
}
Object.preventExtensions(obj4); //不可扩展
console.log(Object.isFrozen(obj4)); //false,非冻结
Object.defineProperty(obj4,'test',{configurable:false});//不可配置
console.log(Object.isFrozen(obj4)); //true,冻结
var obj5 = {x:1};
Object.freeze(obj5);
console.log(Object.isFrozen(obj5)); //true,冻结
console.log(Object.isSealed(obj5)); //true,封闭
console.log(Object.isExtensible(obj5)); //false,不可扩展
JavaScript中的内建对象值Object对象
内建对象 ->数据封装对象:
(1)Object对象
定义:Object是Javascript中所有对象的父级对象,我们创建的所有对象都继承于此,包括内建对象
语法: new Object([value])
{name:value,name:value…}
描述:Object构造函数为给定的值创建一个对象包装。如果给定值是null or undefined,将会创建并返回一个
当以非构造函数形式被调用时,Object等同于new Object().
属性: Object.prototype: 可以为所有Object类型的对象添加属性。
(2)Object.prototype
(3)Number对象
(4)Boolean对象
(5)String对象
(6)Array对象
(7)Function对象
//Object.keys使用
var arr = ['a','b','c'];
console.log(Object.keys(arr)); //["0", "1", "2"]
var obj ={
0:'d',
1:'e',
2:'f'
};
console.log(Object.keys(obj)); // ["0", "1", "2"]
var obj1 = Object.create({},{
getFoo:{
value:function(){
return this.foo;
}
}
});//creat 新建一个对象
obj1.foo = 123;
console.log(Object.keys(obj1)); //["foo"]
//如果想获取一个对象的所有属性,包括不可枚举的,Object.getOwnPropertyNames();
console.log(Object.getOwnPropertyNames(arr)); //["0", "1", "2", "length"]
console.log(Object.getOwnPropertyNames(obj)); //["0", "1", "2"]
console.log(Object.getOwnPropertyNames(obj1));//["getFoo", "foo"]
//Object.getOwnPropertyDescriptor使用
var obj = {get foo(){return 123;}};
console.log(Object.getOwnPropertyDescriptor(obj,'foo'));//Object {set: undefined, enumerable: true, configurable: true, get: function}
obj = {
name:'samuelandkevin',
age:22
};
console.log(Object.getOwnPropertyDescriptor(obj,'name'));//Object{value: "samuelandkevin", writable: true, enumerable: true, configurable: true}
obj = {};//创建一个空对象
Object.defineProperty(obj,'test',{
value:'this is a test',
writable:false,
enumerable:false,
configurable:true
});
console.log(Object.getOwnPropertyDescriptor(obj,'test'));//Object {value: "this is a test", writable: false, enumerable: false, configurable: true}
var obj1 = {x:1};
var obj2 = Object.create(obj1);
console.log(Object.getOwnPropertyDescriptor(obj2,'x')); //undefined .自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性
console.log(Object.getPrototypeOf(obj2)); //Object {x: 1} , obj2的原型是obj1
console.log(Object.getPrototypeOf(obj2)===obj1); //true
//Object.prototype.constructor:返回一个指向创建了该对象原型的函数引用
var obj3 =new Object;
console.log(obj3.constructor===Object); //true
var arr = new Array;
console.log(arr.constructor === Array); //true
function Test(){
}
var f = new Test();
console.log(f.constructor); //function Test(){}
console.log(f.toString()); //[object Object]
Test.prototype.toString = function(){
return '这是自定义的toString';
}
console.log(f.toString()); //这是自定义的toString
var toString = Object.prototype.toString;
console.log(toString.call(new Date)); //[object Date]
console.log(toString.call(new String)); //[object String]
console.log(toString.call(Math)); //[object Math]
console.log(toString.call(undefined)); //[object Undefined]
console.log(toString.call(null)); //[object Null]
//Object.prototype.isPrototypeOf():检测一个对象是否存在另外一个对象的原型链上
//Object.prototype.propertyIsEnumerable():检测指定的属性名是否是当前对象可枚举的自身属性
//Object.prototype.toString():返回一个代表该对象的字符串
//Object.prototype.valueOf():返回的是this值,即对象本身
JavaScript中的Number对象和Boolean对象
var n = Number('123.123'); //不利用构造器构造
console.log(n); //123.123
console.log(typeof n); //number
var n2 = new Number('123.123'); //利用构造器构造
console.log(n2); //Number {[[PrimitiveValue]]: 123.123}
console.log(typeof n2); //object
console.log(Number.NEGATIVE_INFINITY);
console.log(Number.POSITIVE_INFINITY);
console.log(Number.MAX_VALUE);
console.log(Number.MIN_VALUE);
console.log(Number.NaN);
console.log(Number.isNaN(NaN)); //true
console.log(Number.isNaN(0/0)); //true
console.log(Number.isNaN(Number.NaN));//true
console.log(Number.isNaN('')); //false
console.log(Number.isNaN(true)); //false
console.log(Number.isNaN('hello')); //false
console.log(Number.isNaN(undefined)); //false
console.log(Number.isNaN(' ')); //false
var n3 = 12345.6789
console.log(n3.toFixed()); //12346
console.log(n3.toFixed(1));//12345.7
console.log(n3.toFixed(2));//12345.68
console.log(2.45.toFixed(1));//2.5
console.log(1.23e-20.toFixed(2));//0.00
var n4 = 77.12563
console.log(n4.toExponential());//7.712563e+1
console.log(n4.toExponential(1));//7.7e+1
console.log(n4.toExponential(2));//7.71e+1
console.log(n4.toExponential(3));//7.713e+1
var n5 = 5.123456
console.log(n5.toPrecision());//5.123456
console.log(n5.toPrecision(1));//5
console.log(n5.toPrecision(2));//5.1
console.log(n5.toPrecision(3));//5.12
var n6 = new Number(255);
console.log(n6.toString());//255
console.log(n6.toString(8));//377
console.log(n6.toString(10));//255
console.log(n6.toString(16));//ff
console.log(n6.toString(2));//11111111
//测试布尔值对象
var b = new Boolean();
console.log(typeof b); //object
console.log(b.valueOf()); //false
console.log(typeof b.valueOf()); //boolean
var b1 = new Boolean(0);
console.log(typeof b1.valueOf());//boolean
var b2 = new Boolean(-0);
console.log(typeof b2.valueOf());//boolean
var b3 = new Boolean(undefined);
console.log(typeof b3.valueOf());//boolean
var b4 = new Boolean(false);
console.log(typeof b4.valueOf());//boolean
var b5 = new Boolean(null);
console.log(typeof b5.valueOf());//boolean
var b6 = new Boolean('');
console.log(typeof b6.valueOf());//boolean
JavaScript中内建对象-String对象
JavaScript中内建对象-Function对象
JavaScript中内建对象-Math对象
JavaScript中对象的属性
JavaScript中对象的原型属性-prototype
function foo(a,b){
return a*b;
}
console.log(foo.length); //参数的个数,2
console.log(foo.constructor); // fucntion Function() { [native code] }
console.log(foo.prototype); //Object {}
function Production(name,color){
this.name = name;
this.color = color;
this.whatAreYou = function(){
return 'this is a ' + this.color + ' ' + this.name;
};
}
Production.prototype = {
price:6888,
memory:64,
getInfo:function(){
return '内存' + this.memory + '--价钱:' + this.price;
}
}
var p1 = new Production('iPhone6s','玫瑰金');
console.log(p1.name); //iPhone6s
console.log(p1.color); //玫瑰金
console.log(p1.whatAreYou());//this is a 玫瑰金 iPhone6s
console.log(p1.price);
console.log(p1.memory);
console.log(p1.getInfo()); //内存64--价钱:6888
//自定义get方法
Production.prototype.get = function(what){
return this[what];
}
console.log(p1.get('price')); //6888
console.log(p1.get('memory')); //64