javascript数组原型方法

时间:2022-08-24 22:30:50

1.javascript数组原型方法。

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>jstest</title>
  6 </head>
  7 <body>
  8     <script>
  9        var arr = ["1","2","3"];
 10         arr.baz = "baz";
 11         console.log(arr);   //  数组也是对象,添加属性后,并不会改变它的长度;
 12         var myObj = {
 13             a:2
 14         }
 15        console.log(  Object.getOwnPropertyDescriptor(myObj,"a"));
 16         Object.defineProperty(myObj,"a",{
 17             value:3,
 18             writable:false,
 19             enumerable:true,
 20             configurable:true
 21         })
 22 
 23         myObj.a = 4;
 24         console.log(myObj.a);  //3  定义属性描述不可写,无法修改值
 25         //属性描述符里有get和set两个,分别表示读写。
 26 
 27         //当configurable为false时,属性没法修改 ,没法delete删除,有个例外,可以把writable由true改为false。
 28         // 只要属性是可配置的,就可以用 Object.defineProperty()设置属性描述符。
 29 
 30         /*要设置对象或属性不可变:
 31            1.常量对象:结合 writable:fasle和configurable:false创建常量属性(不可修改,重定义,删除)。
 32            2.禁止扩展:禁止对象添加新属性,保留已有属性,使用 Object.preventExtensions(obj);
 33            3.密封:Object.seal() 会创建一个密封的对象,实际上是在现有对象的基础上调用preventExtensions,
 34              并把所有现有属性标记为false;
 35            4.冻结:Object.freeze() 会创建一个冻结对象,他在原有对象的基础上,调用seal()并把所有数据访问的属性标记为
 36               writable:false,这是级别最高的不可变性。
 37          */
 38          var b={ a:undefined }
 39         console.log(b.a);  //undefined
 40         console.log(b.b);  //undefined
 41 
 42         /*
 43          上面的两个结果都为undefined,区别在于内部的get操作。
 44          可以判断属性的存在性,去区别这两种情况:
 45         */
 46         console.log("a" in b);   //true
 47         console.log("b" in b);   //false
 48        // 或者
 49        console.log(b.hasOwnProperty("a"));  //true
 50        console.log(b.hasOwnProperty("b"));   //false
 51        /*
 52         上面两种方式的区别在于:
 53         1.in会检查属性是否存在于对象或其原型链中,
 54         2.hasOwnProperty只检查属性是否存在于对象中,不检查原型链。
 55 
 56         注意:in操作符检查的是属性,不是值, 2 in [1,2]并不是true,
 57        */
 58 
 59         /*
 60          可枚举性:设为false的时候,它不会出现在对象属性的循环遍历中。下面例子:
 61         */
 62         var obj= {}
 63         Object.defineProperty(obj,"a",{
 64             value:2,
 65             enumerable:true
 66         });
 67         console.log(obj.a);
 68         Object.defineProperty(obj,"b",{
 69             value:3,
 70             enumerable:false
 71         })
 72         console.log(obj.b);
 73         // 检测存在性
 74         console.log("a" in obj);
 75         console.log("b" in obj);
 76 
 77         console.log( obj.hasOwnProperty("a"));
 78         console.log(obj.hasOwnProperty("b"));
 79 
 80         // 进行循环
 81         for(var k in obj){
 82             console.log(k,obj[k])   // 结果  a 2
 83         }
 84        /* 以上结果表明 enumerable设为false的时候,属性仍存在,但不会被遍历。
 85            同时,for  in 循环,用来遍历数组的话,有可能会把数组中的非数字索引遍历到,所以
 86            数组循环,最好用传统的for循环,看下面例子:
 87      */
 88         var arr = [1,2,3]
 89         arr.baz = "baz";
 90         for(var k in arr){
 91             console.log(k,arr[k]);
 92         }
 93         /*结果  0 1
 94                1 2
 95                2 3
 96                baz baz
 97          */
 98         /*
 99         forEach() 会遍历数组中的所有值,并忽略回调函数的返回值。
100          */
101         var arr =  [1,2,3,4,5]
102         arr.forEach(function(value){
103             console.log(value,"forEach");
104         })
105 
106        //every() 函数一直运行,直到回调函数返回false值,或者遍历结束。
107        //这里需要返回值,是说每次循环都要有返回值,也就是说
108        //if条件不满足的时候,也要进行return
109        var i = 0;
110        arr.every(function(value){
111            i+=value;
112            console.log("every",value)
113 //           return value<3
114             if(i>20){
115                 return false
116             }else{
117                 return true
118             }
119        })
120         // 跟上边的every()类似,some() 函数会在返回值是真的时候停止。 简单例子:
121         arr.some(function(value){
122             console.log(value,"some");
123             return value>2
124         })
125 
126         //不通过下标,直接遍历数组:ES6 方法;
127         for(var v of arr){
128             console.log(v,"for...of");
129         }
130         //for...of... 实际上是通过对象的迭代器对象,调用next()方法来实现遍历的。
131         //下面用原生内置的 @@iterator手动遍历:
132         var arr = [1,2,3,4];
133         var it = arr[Symbol.iterator]();
134         console.log(it.next().value,"iterator");
135         console.log(it.next().value,"iterator");
136         console.log(it.next().value,"iterator");
137         console.log(it.next().value,"iterator");
138         console.log(it.next().value,"iterator");
139 
140 
141         //给对象定义迭代器:举例:
142         var obj = {
143             a:2,
144             b:3
145         }
146         Object.defineProperty(obj,Symbol.iterator,{
147             enumerable:false,
148             writable:false,
149             configurable:true,
150             value:function(){
151                 var o = this,idx = 0,ks = Object.keys(o);
152                 return {
153                     next:function(){
154                         return {
155                             value:o[ks[idx++]],
156                             done:(idx>ks.length)
157                         }
158                     }
159                 }
160             }
161         })
162         //根据定义好的iterator 进行手动迭代:
163         var it = obj[Symbol.iterator]();
164         console.log(it.next(),"手动迭代")
165         console.log(it.next(),"手动迭代")
166         console.log(it.next(),"手动迭代")
167         //for of  遍历
168         for(var v of obj){
169             console.log(v,"forof");
170         }
171 
172         // 你可以定义一个无限迭代:
173        var randoms = {
174            [Symbol.iterator]:function(){
175                return {
176                    next:function(){
177                        return { value:Math.random()}
178                    }
179                }
180            }
181        };
182        var randoms_pool = [];
183         for(var n of randoms){
184             randoms_pool.push(n);
185             if(randoms_pool.length ===100){
186                 console.log(randoms_pool);
187                 break;
188             }
189         }
190       //这个迭代器会生成无数个随机数,因此添加break阻止。
191 
192       //原型
193       var obj = {
194           a:2
195       };
196       var newobj = Object.create(obj)
197 
198        console.log("a" in newobj);   //true
199        console.log(newobj.hasOwnProperty("a")); //false
200        // 上面的结果表明,a属性,存在于newobj的原型链中,但不属于它本身。
201         newobj.a++;
202         console.log(newobj.a);   //3
203         console.log(obj.a);   //2
204        //上面就是一个隐式屏蔽,下层不会改变上层的值,还有一个情况就是,上层会改变下层的值
205 
206         /*
207          我们只需要两个对象就可以判断他们之间的关系,举例:
208          b是否出现在c的原型链中:  b.isPrototypeOf(c)
209            也可以直接获取一个对象的原型链:
210           */
211          var new2obj = Object.create(newobj);
212          console.log(Object.getPrototypeOf(new2obj));
213     </script>
214 </body>
215 </html>