目录
12.1字符串
12.1.1特效标签
12.1.2字符串截子串
12.2 数组
12.3时间
12.4Math
12.5遍历器
1、for循环
2、forin循环 (es5的技术)
3、while循环
4、do-while循环
5、ArrayforEach循环
6、Arraymap()方法
7、Arrayfilter()方法
8、Arraysome()方法
10、Arrayreduce()方法
11、ArrayreduceRight()方法
12、forof循环 (Es6 )
12.6 对象成员检测
1.instanceof:
2. isPrototypeOf:
3. hasOwnProperty()
4. propertyIsEnumerable():
12.7 Object静态方法
1.静态方法
2.Object类的静态方法
(1) Object.getPrototypeOf(obj)
(2) Object.getOwnPropertyNames(obj)
(3) Object.defineProperty(obj,propName,desc)
(4) Object.create(proto,[props])
(5) Object.getOwnPropertyDescriptor(obj,propName)
(6) Object.preventExtensions(obj)
(7) Object.seal(obj)
(8) Object.freeze(obj)
12.8 对象序列化
12.9 正则表达式
12.1字符串
12.1.1特效标签
big——就是给文字加特效
var str = "hello,world"
var re=str.big() //原字符串str没有改变
console.log(typeof re) //string
console.log(re) //<big>hello,world</big>
re=str.anchor("")
re=str.link("")
re=re.bold()
re=str.blink()
re=str.fontcolor("red")
re=str.fontsize("30px")
re=str.italics()
re=str.small()
re=str.sup()
re=str.sub()
以上特效的 万能方式:
主要思想:在原型上加方法,所以字符串就可以调,调之后return返回一个新的字符串,新字符串是基于this的
String.prototype.mytool=function mytool () {if(arguments.length){var color=arguments[0]var font=arguments[1]var link=arguments[2]//return '<a href="'+link+'" style="font:'+font+';color:'+color+'">'+this+'</a>'return `<a href="${link}" style="font:${font};color:${color}">加特效的方法</a>`}return '<a href="https://www./">'+this+'</a>'}var box=document.querySelector(".box")var str="加特效的方法 "re=str.mytool()re=str.mytool("red","20px","https://www./")box.innerHTML=reconsole.log(re,str)
首字母大写: (可用此思想设计把其中哪一个字母/汉字变大、变颜色等)
String.prototype.capUppserCase=function() {var re=this[0].toUpperCase()for(var i=1;i<this.length;i++){re+=this[i]}return re}var str="poStasdasdf"var re=str.capUppserCase()console.log(re)
String.prototype.capUppserCase=function() {var re=this[0].bold()var re2=this[1].bold()re+=re2for(var i=2;i<this.length;i++){re+=this[i]}return re}var str="全国计算机等级考试报名通知 一、报考5月全国计算机等级考试的考生严格按照《重庆市5月全国计算机等级考试报名公告》(附件1)的要求报...学术信息 | ACADEM"var re=str.capUppserCase()console.log(re)var box=document.querySelector(".box")box.innerHTML=re //全国变粗
12.1.2字符串截子串
substr ——取下标 左右都闭 不改变原字符串 注意不是驼峰命名法
var str="hello"
var re = str.substr(1,3) //ell
// var re = str.substr(-5,1) //h
console.log(re)
substring ——左开右闭 数字代表第几个,不是下标
var str="hello"
var re = str.substring(1,3) //(1,3] el
// var re = str.substring(-1,3) //hel
console.log(re)()
slice 与 substring的区别
var str="hello"
var re = str.slice(1,3) //el
// var re = str.slice(-1,3)
console.log(re)
split一定会返回一个数组,可以不传参,不改变原字符串
var str="hello"
var arr=str.split("e") //h llo
var arr=str.split("") //h e l l o
var arr=str.split("q") //hello
var str="helxxlo"
var arr=str.split("l") //he xx o
console.log(arr)
对象的属性名其实是一个字符串,所以一般都要加引号,但很多时候我们都没加 "name":"jack"
var a="b" //让obj{b:20}
obj.a=20 //此方法不行
obj[a]=20 //此方法可以 表示obj有一个属性是b
obj["a"]=20 //表示obj有一个属性是a
笔试题原题:把当前网页的url的参数解析为一个对象
window.location.href //获取当前网页的地址、网址var url='/index.html?user=karen&page=10&count=100'function parseurl(str) {var querystring=str.split("?")[1]var arr=querystring.split("&")//["user=karen","page=10","count=100"]var obj={}for(var i=0;i<arr.length;i++){var arr2=arr[i].split("=")obj[arr2[0]]=arr2[1]}return obj}var obj=parseurl(url) //{user:"karen",page:"10",count:"100"}console.log(obj)
indexOf 检测位置,返回数组的小标。-1就代表没有,第二个参数不写默认为0
var str="abcdea"
var re=str.indexOf("cde") //2
var re=str.indexOf("a") //0
var re=str.indexOf("a",2) //5 从数组下标2开始检测a的位置
var re=str.indexOf("a",0) //0
console.log(re)
预测笔试题
String.prototype.count1=function(str) {var re=-1;var count=0do{re=this.indexOf(str,re+1)if(re!=-1){count++}}while(re!=-1)return count}var str="的1935年秋,原在浙西南坚持游击斗争红军挺进师,在刘英和粟裕率领下,冲破蒋军重重封这是叶飞和粟裕、刘英第二次会面了。上一次会面,是在1934年8月,由红7军团组成北上抗日先遣队路经闽东,叶飞发动地方组织,为先遣队补充了不少兵员和给养。"var re=str.count1("的")console.log(re)//的出现的次数
toString
var str="hello"
var re=str.toString()
console.log(re) //hello
valueOf
对象是一种引用数据,字符串是基础数据
var str="hello"
var re=str.valueOf()
console.log(re,typeof re) //hello string
var strobj=new String("hai")
var re2=strobj.valueOf()
console.log(strobj,typeof strobj,re2) //String{'hai'} object hai
var str="100"
console.log(typeof str.toString()) //100 这是string
console.log(typeof str.valueOf()) //100 这是string
基本数据(也称原始数据,不可分割)和引用数据的区别——包装对象
.语法是一种引用数据的语法糖,只有引用数据才有 标准写法 obj[]
str.split() //那为什么字符串可以点语法,就用到包装对象
隐式操作 因为字符串是基本数据 所有所有的基本数据当做对象使用时 它们的点语法 都会多一步隐式操作 (隐式包装成一个对象)。包装对象会销毁
基本数据是不可以保存数据的
var str="hello"
str.age=20
//str.age=20 的 隐式操作
//var str=new String("hello")
//str.age=20
var re=str.age
//var re=str.age 的 隐式操作
//var str=new String("hello") //这个对象和上面的对象是两个对象
// var re=str.age
console.log(re) //und
//所以str可以调split方法
str.split("o")
// var str=new String("hello")
// str.split("o")
//str对象的原型对象是String.prototye。原型对象上面就有split方法
console.log(String.prototype)
12.2 数组
12.3时间
getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。
-----整个地球分为二十四时区,每个时区都有自己的本地时间。在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为通用协调时UTC(UTC, Universal Time Coordinated),UTC与格林尼治平均时(GMT, Greenwich Mean Time)一样,都与英国伦敦的本地时相同北京时区是东八区:+0800,领先UTC八个小时
控制台有颜色就是数字。有的在控制台看是字符串,但是可能是对象。字符串没有折叠面板
var dt=new Date() //在当前运行代码时,创建一个时间点对象console.log(dt.getDate()) //几号console.log(dt.getDay()) //周几 周天=7//下周是多久,就直接+7天,下个月就需要看天数了console.log(dt.getFullYear()) //4位数的年份console.log(dt.getYear()) //3位的年 122后两位是年份console.log(dt.getMonth()) //重点!范围是0-11 所以一般显示时间,是+1console.log(dt.getMonth()+1) console.log(dt.getHours()) //重点!名字要记得:大写+s。 不能取到24//笔试题:getHours getHour gethours gethourconsole.log(dt.getMinutes()) //分钟console.log(dt.getSeconds()) //秒console.log(dt.getMilliseconds()) // 1000ms=1sconsole.log(dt) //Mon May 23 20:12:25 GMT+0800 (中国标准时间) 它是一个对象,不是字符串console.log("Mon May 23 20:12:25 GMT+0800 (中国标准时间) ") //这是字符串//可以算那个时间是周几...var dt2=new Date("1999-02-02")console.log(dt2) //Tue Feb 02 1999 08:00:00 GMT+0800 (中国标准时间)console.log(dt.getTime()) //1653308676057 这个代表1970-01.....时间开始多少ms
----new Date(ms)
//把毫秒数转换为Date对象,表示从'1970/01/01 00:00:00'为起点,开始叠加的毫秒数,注意:起点的时分秒还要加上当前所在的时区,北京时间的时区为东8区,起点时间实际为:'1970/01/01 08:00:00'
var dt = new Date(1000 * 60 * 1); // 前进1分钟的毫秒数console.log(dt); // 1970/01/01 08:01:00dt = new Date(-1000 * 60 * 1); // 倒退1分钟的毫秒数console.log(dt); //1970/01/01 07:59:00var dt3=new Date(1000)//可以传msconsole.log(dt3) //Thu Jan 01 1970 08:00:01 GMT+0800 (中国标准时间)
----new Date(dateStr)//把字符串转换为Date对象
换为Date对象的字符串(可省略时间)的格式主要有两种:
yyyy/MM/dd HH:mm:ss(都用的这种)若省略时间,返回的Date对象的时间为 00:00:00。
yyyy-MM-dd HH:mm:ss若省略时间,返回的Date对象的时间为 08:00:00(加上本地时区),若不省略时间,此字符串在IE中会转换失败
var dt = new Date('/12/25'); // yyyy/MM/ddconsole.log(dt); // /12/25 00:00:00dt = new Date('/12/25 12:00:00'); // yyyy/MM/dd HH:mm:ssconsole.log(dt); ///12/25 12:00:00dt = new Date('-12-25'); // yyyy-MM-ddconsole.log(dt); //-12-25 08:00:00 (加上了东8区的时区)dt = new Date('-12-25 12:00:00'); // yyyy-MM-dd HH:mm:ss (注意:此转换方式在IE中会报错!)console.log(dt); // -12-25 12:00:00
----new Date(year, month, opt_day, opt_hours, opt_minutes, opt_seconds, opt_milliseconds)
把年月日、时分秒转换为Date对象//option
参数:
year:年份4位数字,如:1999、
month:月份2位数字,从0开始计算,0表示1月份、11表示12月份。
opt_day可选号2位数字,从1开始计算,1表示1号。
opt_hours可选时2位数字,取值0~23。
opt_minutes可选分2位数字,取值0~59。
opt_seconds可选秒2位数字,取值0~59。
opt_milliseconds可选毫秒,取值0~999。
var dt = new Date(, 1); // 2月(这里输入的月份数字为1)console.log(dt); // /2/01 00:00:00dt = new Date(, 1, 25); // 2月25日console.log(dt); ///2/25 00:00:00dt = new Date(, 1, 25, 15, 30, 40); // 2月25日 15点30分40秒console.log(dt); // /2/25 15:30:40dt = new Date(, 12, 25); // 13月25日(这里输入的月份数字为12,表示第13个月,跳转到第二年的1月)console.log(dt); // /01/25
====实例方法
Date对象的方法分为2种形式:本地时间和UTC时间。同一个方法,一般都会有2种时间格式操作(方法名带UTC的,就是操作UTC时间),我们主要学习本地时间的操作。
----get方法
getFullYear() 返回Date对象的年份值;4位年份。
getMonth() 返回Date对象的月份值。从0开始,所以真实月份=返回值+1 。
getDate() 返回Date对象的月份中的日期值;值的范围1~31 。
getHours() 返回Date对象的小时值。
getMinutes() 返回Date对象的分钟值。
getSeconds() 返回Date对象的秒数值。
getMilliseconds()返回Date对象的毫秒值。
getDay() 返回Date对象的一周中的星期值;0为星期天,1为星期一
getTime() 返回Date对象与'1970/01/01 00:00:00'之间的毫秒值(北京时间的时区为东8区,起点时间实际为:'1970/01/01 08:00:00')
dt.getFullYear(); // dt.getMonth(); //1实际为2月份(月份从0开始计算)dt.getDate(); // 25dt.getHours(); // 15dt.getMinutes(); // 36dt.getSeconds(); // 21dt.getMilliseconds(); // 125dt.getDay(); //dt.getTime(); // 返回Date对象与'1970/01/01 00:00:00'之间的毫秒值(北京时间的时区为东8区,起点时间实际为:'1970/01/01 08:00:00')
----set方法
setFullYear(year, opt_month, opt_date)设置Date对象的年份值;4位年份。
setMonth(month, opt_date) 设置Date对象的月份值。0表示1月,11表示12月。
setDate(date)设置Date对象的月份中的日期值;值的范围1~31 。
setHours(hour, opt_min, opt_sec, opt_msec)设置Date对象的小时值。
setMinutes(min, opt_sec, opt_msec)设置Date对象的分钟值。
setSeconds(sec, opt_msec) 设置Date对象的秒数值。
setMilliseconds(msec) 设置Date对象的毫秒值。
var dt = new Date();dt.setFullYear(); // => dt.setMonth(11); // 11实际为12月份(月份从0开始计算)dt.setDate(25); // 25dt.setHours(15); //15dt.setMinutes(30); // 30dt.setSeconds(40); // 40dt.setMilliseconds(333); //333console.log(dt); // 12月25日 15点30分40秒 333毫秒
-----to方法
toString() 将Date转换为一个 '年月日 时分秒' 字符串
toLocaleString() 将Date转换为一个'年月日 时分秒'的本地格式字符串
toDateString() 将Date转换为一个'年月日'字符串
toLocaleDateString() 将Date转换为一个'年月日'的本地格式字符串
toTimeString() 将Date转换为一个'时分秒'字符串
toLocaleTimeString() 将Date转换为一个'时分秒'的本地格式字符串
valueOf() 与getTime()一样,返回Date对象与'1970/01/01 00:00:00'之间的毫秒值(北京时间的时区为东8区,起点时间实际为:'1970/01/01 08:00:00')
var dt = new Date();console.log(dt.toString()); // Tue Dec 25 20:56:11 GMT+0800 (中国标准时间) console.log(dt.toLocaleString()); //12月25日 下午8:56:11 console.log(dt.toDateString()); // Tue Dec 23 console.log(dt.toLocaleDateString()); // 12月25日 console.log(dt.toTimeString()); //20:56:11 GMT+0800 (中国标准时间) console.log(dt.toLocaleTimeString()); //下午8:56:11console.log(dt.valueOf()); //返回Date对象与'1970/01/01 00:00:00'之间的毫秒值(北京时间的时区为东8区,起点时间实际为:'1970/01/01 08:00:00')
----类方法(静态方法)
Date.now() 返回当前日期和时间的Date对象与'1970/01/01 00:00:00'之间的毫秒值(北京时间的时区为东8区,起点时间实际为:'1970/01/01 08:00:00')
console.log(Date.now()); // 1419431519276
Date.parse(dateStr)把字符串转换为Date对象 ,然后返回此Date对象与'1970/01/01 00:00:00'之间的毫秒值(北京时间的时区为东8区,起点时间实际为:'1970/01/01 08:00:00')
参数2种:
yyyy/MM/dd HH:mm:ss若省略时间(大家都使用这种方法),返回的Date对象的时间为 00:00:00。
yyyy-MM-dd HH:mm:ss若省略时间,返回的Date对象的时间为 08:00:00(加上本地时区)。若不省略时间,此字符串在IE中返回NaN(非数字)
console.log(Date.parse('/12/25 12:00:00')); // 1419480000000
console.log(Date.parse('-12-25 12:00:00')); // 1419480000000 (注意:此转换方式在IE中返回NaN)
----两个Date的时间差,返回两者相差的毫秒数
var dt1 = new Date('/12/01');
var dt2 = new Date('/12/25');
console.log(dt1 > dt2); // false
console.log(dt1-dt2)//返回两者相差的毫秒数
----倒计时:X天X时X分
计算当前时间离目的时间相差多少天时分。
function getDownTime(dt) {// 1.获取倒计时var ms = dt - Date.now(); // 目的时间减去现在的时间,返回两者相差的毫秒数var s = parseInt(ms/ 1000%60); // 秒var day = parseInt(ms/ 3600/1000 / 24); // 天数var hour = parseInt((ms/1000- day * 24 * 3600) / 3600); // 小时var m = parseInt((ms/1000- day * 24 * 3600 - hour * 3600) / 60); // 分钟return '倒计时: ' day + '天' + hour + '时' + m + '分'+s+”秒”}console.log(getDownTime(new Date('/1/01')))
创建时间的几种方式
var nowdt=new Date()var sindt=new Date("Mon May 23 20:12:25 GMT+0800 (中国标准时间)")var absdt=nowdt-dinsdtconsole.log(absdt)if(absdt<1000*60) {"刚刚"}else if (1000*60<=absdt&&absdt<1000*60*60) {var re=new Date(absdt).getMinutes()}
//注意:可以超出,会自动进位var dt6=new Date(,2,34,08,30,40)console.log(dt6) //Thu Apr 03 08:30:40 GMT+0800 (中国标准时间)//自动进位了,传入2,系统就会进位到3,3就是四月
12.4Math
var deg=Math.PI/180var re =36*deg //36°
var n=8.19console.log(Math.ceil(n)) //9console.log(Math.floor(n)) //8console.log(Math.round(n)) //8//全局函数var re=parseFloat("1234.12px123") console.log(re) //1234.12var re1=parseInt("1234.12px123") //向下取整console.log(re1) //1234//数字的方法var n=8.19var re2=n.toFixed(1) //保留几位小数console.log(re2) //8.2//~~ 去掉小数点,向下取整 (一般不用)var n=8.19var re3=~~n console.log(re3) //8//sinvar deg=Math.PI/180var re4=Math.sin(90*deg)console.log(re4) //1//一般用法:给一个坐标,给你五角星的r,中心点,让你画出五角星//random 返回0-1之间的随机数 伪随机数var re5 = Math.random()console.log(re5)console.log(re5*10) //范围[0,10)console.log(re5*15-2)//范围是(-2,13)
12.5遍历器
1、for循环
for循环是Js中最常用的一个循环工具,经常用于数组的循环遍历。
letarr=[1,2,3];
for(leti=0;i<arr.length;i++){
console.log(i,arr[i])
}
2、forin循环 (es5的技术)
forin循环主要用于遍历普通对象,i代表对象的key值,obj[i]代表对应的value,当用它来遍历数组时候,多数情况下也能达到同样的效果,但是你不要这么做,这是有风险的,因为i输出为字符串形式,而不是数组需要的数字下标,这意味着在某些情况下,会发生字符串运算,导致数据错误,比如:'52'+1='521'而不是我们需要的53。
另外forin循环的时候,不仅遍历自身的属性,还会找到prototype上去,所以最好在循环体内加一个判断,就用obj[i].hasOwnProperty(i),这样就避免遍历出太多不需要的属性。
var obj={s1:20,s2:"karen",length:2}obj.__proto__={life:1}for (var key in obj) {console.log(key) // s1 s2 length life}
//3、while循环
同样的遍历cars数组,先用for循环方法
letcars=["BMW","Volvo","Saab","Ford"];
leti=0;
for(;cars[i];){
console.log(cars[i])
i++;
};
//然后是while循环方法
cars=["BMW","Volvo","Saab","Ford"];
vari=0;
while(cars[i]){
console.log(cars[i]+"<br>")
i++;
};
//我们发现,它们可以实现同样的效果,事实上它们底层的处理是一样的,不过for循环可以把定义、条件判断、自增自减操作放到一个条件里执行,代码看起来方便一些,仅此而已。
//4、do-while循环
leti=3;
do{
console.log(i)
i--;
}
while(i>0)
//do-while循环是while循环的一个变体,它首先执行一次操作,然后才进行条件判断,是true的话再继续执行操作,是false的话循环结束。
//5、ArrayforEach循环
forEach循环,循环数组中每一个元素并采取操作,没有返回值,可以不用知道数组长度,。
他有三个参数:el(是必需的,代表当前下标下的value),index(打印当前值的下标),arr(调用者,就是数组 本身)后面两个参数可以不设
另外请注意,forEach循环在所有元素调用完毕之前是不能停止的,它没有break语句,如果你必须要停止,可以尝试try-catch语句,就是在要强制退出的时候,抛出一个error给catch捕捉到,然后在catch里面return,这样就能中止循环了,如果你经常用这个方法,最好自定义一个这样的forEach函数在你的库里。
forEach返回值是und。调用的次数确定
var arr = [10, 203, 44]var re = arr.forEach(function (el) {console.log(el) //10 203 44})console.log(re) //undvar arr = [1, 2, 3];arr.forEach(function (i, index) {console.log(i, index,arr) //结果为:第一排1 0 [1, 2, 3] 第二排: 2 1 [1, 2, 3] 第三排 3 2 [1, 2, 3]})//因为数组里面有三个元素,所以调用了三次
根据forEach,设计myforEach (笔试题会考,所以需要掌握思想)
var arr = [10, 203, 44]Array.prototype.myforEach = function (callback) {for (var i = 0; i < this.length; i++) {callback(this[i])}}var re = arr.myforEach(function (el) {console.log(el) //10 203 44})
//6、Arraymap()方法
//map()方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后,返回的值。
注意:map和forEach方法都是只能用来遍历数组,不能用来遍历普通对象。
有返回值,要自己亲自设计出一个函数,能够使用。调用的次数确定
原数组不改变,和foEach一样,有三个属性,第一个必须有
let arr = [1, 2, 3];let tt = arr.map(function (i) {console.log(i) //1 2 3return i * 2; //将return的值放入一个数组中,作为tt的返回结果。如果不写return,那就是数组里面放了三个undconsole.log(tt) //(3)[2, 4, 6]
var arr = [{name:"karen",birth:"2001-02-03"},{name:"jack",birth:"2002-02-03"}]var arr2=arr.map(function(el){el.age=new Date().getFullYear()-new Date(el.birth).getFullYear()return el})console.log(arr2) //[{name:"karen",birth:"2001-02-03",age:21},{name:"jack",birth:"2002-02-03",age:20}]
7、Arrayfilter()方法
filter方法是Array对象内置方法,它会返回通过过滤的元素,不改变原来的数组。
返回是新数组,调用的次数确定
var arr=[10,80,34,50]var re=arr.filter(function(el,index,arr){console.log(el) //10 80 34 50return true //就算不写return,也会进行布尔判断,最后返回空数组 //布尔值是true,(可以写return 100...)所以将el取出的值放在新数组re中。//布尔值是false,(可以写return 0或者不写),所以就返回空数组re//也可以写下面的条件// if(el>18){// return true// }else{// return false// } //那么re就是[ 80 34 50]})console.log(re)
var arr=[{tag:0,name:"karen"},{tag:1,name:"jack"},{tag:1,name:"marry"}]//将tag为0的筛选掉var arr2=arr.filter(function(el){return el.tag})console.log(arr2)
8、Arraysome()方法
//some()方法用于检测数组中的元素是否满足指定条件(函数提供),返回boolean值,只要有一个满足条件就返回true
不改变原数组。调用的次数不确定
var arr=[10,200,500,400]var re=arr.some(function(el){console.log(el) //10 200 已经得到了true,就不会在继续了return el>100 //不写return,就代表一个也没通过,最后结果为false})console.log(re) //true
设计mysome
// 预测笔试题设计mysomeArray.prototype.mysome=function(callback) {for(var i=0;i<this.length;i++){if(callback(this[i],i,this)){return true}}return false}var arr=[10,200,500,400]var re=arr.mysome(function(el){console.log(el)return el>100})console.log(re)
//9、Arrayevery()方法
letarr=[1,2,3];
lettt=arr.some(function(i){
returni>1;
})
//检测数组中元素是否都大于1
//false
//every()方法用于检测数组所有元素是否都符合指定条件(通过函数提供),返回boolean值,不改变原数组。
10、Arrayreduce()方法
reduce()方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
第一次辉
var arr=[10,20,4,5]var re=arr.reduce(function(n1,n2){console.log(n1,n2) //第一次打印: 10 20 ,第二次:30 4return n1+n2 //return是30 ,那就作为下一次的n1,一次类推。如果没有返回值,就为und})console.log(re) //最后一次return的结果,作为re的返回结果。39
var arr=[10,20,4,5]var re=arr.reduce(function(n1,n2){console.log(n1,n2)return n1+n2},100) //设置初始值,第一次调用时,n1是100,n2是20console.log(re)
11、ArrayreduceRight()方法
reduceRight()方法,和reduce()功能是一样的,它是从数组的末尾处向前开始计算。
var arr=[100,203,34,50]arr.reduceRight(function (n1,n2){console.log(n1,n2)},0) //n1是0,n2是50 倒着取
12、forof循环 (Es6 )
forof循环是Es6中新增的语句,用来替代
forin和forEach,它允许你遍历Arrays(数组),Strings(字符串),Maps(映射),Sets(集合)等可迭代(Iterabledata)的数据结构,注意它的兼容性。
一般 for of和for in都不怎么用,推荐使用for循环
//可以遍历数组、类数组。 不会取原型链上的var arr=[10,203,34]for (let s of arr) {console.log(s)}
算总价的三种方法:
1. 遍历数据 然后累加 for map for-in for-of foreach ... 一般用这个方法
var arr=[10,203,4,5]var total=0;//for循环可以换为上面所学的map....那些方法for(var i=0;i<arr.length;i++){total+=arr[i]}console.log(total)
第二种:reduce reduceRight()
var arr=[10,20,4,5]var re=arr.reduce(function(n1,n2){console.log(n1,n2) //一次打印: 10 20 ,第二次:30 4return n1+n2 //return是30 ,那就作为下一次的n1,一次类推。如果没有返回值,就为und})console.log(re) //最后一次return的结果,作为re的返回结果。39var arr = [{title: "肉香肉丝",price: 18,count: 2},{title: "米饭",price: 1,count: 5},{title: "水煮肉片",price: 28,count: 1},{title: "鸡公煲",price: 20,count: 1}]//传初始值0的方法var re=arr.reduce(function(n1,n2){return n1+n2.price*n2.count},0)console.log(re)//不传初始值0var re=arr.reduce(function(n1,n2){if(!n1.total){n1.total=n1.price*n1.count+n2.price*n2.count}else{n1.total=n1.total+n2.price*n2.count}return n1})console.log(re)
第3种 不建议(只有全是数字的时候才可以使用。影响性能)
var arr=[10,203,4,5]var re=eval(arr.join("+"))console.log(re)
12.6 对象成员检测
1.instanceof:
判断该对象是否为另一个对象的实例。
function Parent() {} function Child() {}Child.prototype=new Parent()var child=new Child()console.log(child instanceof Parent); //true console.log(child instanceof Child); //true
2. isPrototypeOf:
判断一个对象象是否为一个实例的原型。 ,
function Parent() {} function Child() {}Child.prototype=new Parent()var child=new Child()console.log(Parent.prototype.isPrototypeOf(child)); //trueconsole.log(Child.prototype.isPrototypeOf(child)); //true2,
3. hasOwnProperty()
判断对象是否有某个特定的属性,(注意说的是对象的属性,而不是对象原型的属性)必须用字符串指定该属性。
function Parent() {this.life=1} function Child() {this.name="karen"}Child.prototype=new Parent()var child=new Child()console.log(Parent.hasOwnProperty("name")); //trueconsole.log(Child.hasOwnProperty("age")); //falseconsole.log(Parent.hasOwnProperty("alertP")); //falseconsole.log(Child.hasOwnProperty("alertC")); //false
4. propertyIsEnumerable():
判断给定的属性是否可以用 for...in 语句进行枚举。由于 for ... in 枚举是包含原型链上的属性的,但propertyIsEnumerable作用于原型方法上时,始终是返回false的,你可以这么认为,for...in可以枚举对象本身的属性和原型上的属性,而propertyIsEnumerable只能判断本身的属性是否可以枚举。此外,预定义的属性不是可列举的,而用户定义的属性总是可列举的。所以如果你只想遍历对象本身的属性,可以:
<div class="box">1</div><div class="box">2</div><div class="box">3</div><div class="box">4</div><script>var arr=document.querySelectorAll(".box")console.log(arr)for(var i in arr) {console.log(i)}</script>//for-in能遍历的对象的成员就是可遍历成员
12.7 Object静态方法
1.静态方法
静态方法就是直接使用类名调用的方法,比如Object.getOwnPropertyNames(obj),obj是一个对象,且静态方法是无法被子类继承或者实例对象拥有的
2.Object类的静态方法
(1) Object.getPrototypeOf(obj)
获得obj的原型,也可以使用obj._ proto__属性获得obj的原型:
可以看到对实例变量p使用getPrototypeOf方法可以得到Product.prototype,同时obj一般都是指实例对象,当然对类使用这个方法也可以,但得出的结果没有太大意义,可以自己试一试 Object.getPrototypeOf(Product) 。
fn.prototype=[10,20]var obj=new fn()var re=Object.getPrototypeOf(obj) //就相当于 obj.__prto__console.log(re) //(2)[10, 20]
(2) Object.getOwnPropertyNames(obj)
可以将obj的可枚举和不可枚举的属性的名称组成一个数组返回,例如:
(枚举就是可不可以用for in 去循环)
function Description(sTaste,fPrice){this.taste = sTaste;this.price = fPrice;}function Product(){this.name = "dhs";this.desc = new Description("matcha",7);this.show = function(){alert(this.name + "||" + this.desc.taste + "||" + this.desc.price);}}
实例对象有三个属性。注意只有直接在Product中定义的属性才会被列出来,并且必须是公共属性。
var obj=[10,203,4]var re=Object.getOwnPropertyNames(obj)console.log(obj,re)
(3) Object.defineProperty(obj,propName,desc)
该方法可以为obj新增一个名为propName的属性,同时它的属性定义为desc,desc使用一个对象赋值,例如:
Object.defineProperty(Product.prototype,"a",{value: "a",writable : true,enumerable : true,configurable : true});
以上就为Product的prototype新增了一个名为a的属性,设置它的值为a,可写,可枚举,可更改(可更改的意思是否可更改writable、enumerable等),默认都为true。上面的例子为Product.prototype增加了属性a,那么它所有新的实例对象都会增加这个属性。当然obj本省也可以是实例对象。使用这种方式定义一个新属性,可以自主控制属性的表现方式,如果将writable设置为false,这个属性将不可更改,例如:
将属性a的writable设置为了false,然后更改它的值,虽然没有报错,但是它确实没有被更改,如果在 use strict 模式下,将抛出错误。
//详细定义对象成员var obj={}var temp=nullObject.defineProperty(obj,"age",{set(arg){console.log(arg,6666)temp=arg},get(){// return "hello"return temp+"岁"}})obj.age=100console.log(obj.age) //100岁
(4) Object.create(proto,[props])
工厂函数
以proto为原型,新建一个实例对象,同时将props定义的属性设置给这个新对象,以这种方式新建的对象都是Object类型,例如:
var o = Object.create(Product.prototype,{size : {value : 7,writable : false,enumerable : true,configurable : false}});
//使用create方法新建一个实例对象o,它的父类是Product,它本身属于Object,同时设置size为只读属性。注意这种方式不是使用Product的构造函数新建的实例对象,所以o并没有name、desc等属性。
(5) Object.getOwnPropertyDescriptor(obj,propName)
返回obj的属性propName的属性描述符:
如上面新建的实例对象o,获得它的属性size的属性描述符。
(6) Object.preventExtensions(obj)
可以禁止obj对象的属性扩展,例如:
将实例对象o设置为不可扩展,那么即时给它一个新属性name没有报错,但这个name属性并没有添加到它的定义中。同时size属性的configurable如果设置为true的话,可以使用delete o.size 删除size属性。注意没有preventExtensible的反相操作。
(7) Object.seal(obj)
可以禁止obj对象的属性扩展和删除,它相对与preventExtensible方法而言 ,将所有属性的configurable属性设置为false。
(8) Object.freeze(obj)
可以禁止对obj的所有操作,它相对与preventExtensible方法而言,将属性的configurable属性和writable属性都设置为了false,例如:
如上,实例对象o将不可扩展,属性不可删除,不可更改。
(9) Object.isExtensible(obj)、Object.isSealed(obj)、Object.isFrozen(obj) 分别对应了上述三个方法是否对obj进行了设置
var obj={name:'akren',age:20}var re=Object.keys(obj)console.log(re) //['name', 'age']
var obj={name:'akren',age:20}var re=Object.values(obj)console.log(re) //(2)['akren', 20] 可以把都对象转换为数组
set get
12.8 对象序列化
12.9 正则表达式
12 数据系统内置功能(字符串 数组 时间 Math 遍历器 对象成员检测 Object静态方法 对象序列化 正则表达式)