闭包理解: 突破自身函数作用域的限制,把函数内的局部变量共享到外部。 闭包缺点: 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.//是否可以往该对象添加新的属性 (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,不可扩展内建对象 ->数据封装对象: (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值,即对象本身