js笔记(三)ES5、ES5新增的数组的方法、字符串的方法、字符编码、对象的序列化和反序列化、bind

数组方法、字符串方法总结

大目录小目录
一、ES5严格模式1. 严格模式
2. 严格模式的行为变更
二、ES5新增的数组的方法1. 判断是否为数组:Array.isArray()
2. 判断数组中是否存在某个值:indexOf(data, start)lastIndexOf()
3. ES5新增的遍历数组的方法forEach()map()filter()some()every()
三、字符串的方法(偏ES5)1.判断字符串中是否存在某个字符:indexOf()lastIndexOf()
2. 返回在指定位置的字符或字符编码:charAt(index)charCodeAt()
3. 截取:slice()substr()substring()
4. 字符大小写转换:toLowerCase()toUpperCase()
5. 字符中有关正则的方法:match()replace()search()
6. 字符转成数组:split()
7. 合并字符串:concat()
8. 去除字符串守卫的空格:trim()
四、字符编码1. ASCII
2. Unicode编码
3. GBk
五、ES5对象的序列化和反序列化1. json 转字符JSON.stringify(str); 且转换后是严格写法的 json 格式字符串;
2. 字符转 jsonJSON.parse(str); 要求 str 必须是一个严格写法的 json 格式字符串。否则会报错;
六、ES5函数的方法:bind1. bind 的作用
2. 利用 bind 封装事件委托
3. apply 查找数组中的最小/大值
4. bind/call/apply 的区别

一、ES5严格模式

ie(IE10+)低版本不支持严格模式( js 代码还是能够兼容,只是说不支持严格模式而已)

1.1 严格模式

(1)调用严格模式:
① 全局调用:在要开启严格模式的代码的作用域的第一行添加:"use strict";

② 局部调用:

function fn(){
  "use strict";
  //...
}

③ 匿名函数开启严格模式:(前后都要加 “;”

;(function(){
	"use strict";
})();

(2)作用:
① 消除了 js 语法的一些不合理、不严谨支出,减少一些怪异
② 消除了代码运行的一些不安全之处,保证代码运行的安全;
③ 提高编译器的效率,增加运行速度;
④ 为未来新版本的 js 做好铺垫;

1.2 严格模式的行为变更

严格模式的行为变更:
(1)全局变量声明时,必须使用关键字 var
(2)函数内不允许出现重复名参数;
(3)全局函数中的 this不再指向 window,指向 undefined ;
(4)arguments对象不允许被动态改变;
(5)严格模式下不允许使用 argument.callee
(6)新增保留字: implements、interface、let、package、private、protected、public、static、yield;

(1)全局变量声明时,必须使用关键字 var

a = 10;
console.log(a);//10

"use strict";
a = 10;
console.log(a);//Uncaught ReferenceError: a is not defined

(2)函数内不允许出现重复名参数;

function fn(a,b,b){
	console.log(a);//1
	console.log(b);//3
}
fn(1,2,3);

"use strict";
function fn(a,b,b){
	console.log(a);//1
	console.log(b);//报错
}
fn(1,2,3);

(3)全局函数中的 this不再指向 window,指向 undefined ;

function fn(){
	console.log(this);//指向 window
}
fn();

"use strict";
function fn(){
	console.log(this);//指向 undefined
}
fn();
//window.fn();//此时的this指向window 

(4)arguments对象不允许被动态改变;

function fn(a){
	a = 10;
	console.log(a);//10
	console.log(arguments);//10
}
fn(4);

"use strict";
function fn(a){
	a = 10;
	console.log(a);//10
	console.log(arguments);//4
}
fn(4);

(5)严格模式下不允许使用 argument.callee

"use strict";
function fn(n){
	if(n == 1){
		return 1;
	} else {
		//return n*fn(n-1);
		//或者
		return n*arguments.callee(n-1);
	}
}
console.log(fn(4));//24
//严格模式下报错:Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

(6)新增保留字: implements、interface、let、package、private、protected、public、static、yield;



二、ES5新增的数组的方法

2.1 判断是否为数组:Array.isArray()

结果返回布尔值,数组返回true,非数组返回falsetypeof()无法区分数组和对象,此方法可以 。

var arr = [1,3,5];
var obj = {name:"a",age:18};
console.log( Array.isArray(arr) );  //true
console.log( Array.isArray(obj) );  //false
console.log( typeof(arr) );  //object
console.log( typeof(obj) );  //object
2.2 判断数组中是否存在某个值:indexOf(data, start)lastIndexOf()

(1)indexOf(data, start),返回要查找数值在数组中的索引,若没有就是 -1

var arr = [3,5,6,9,8,2];
console.log(arr.indexOf(5)); //1
console.log(arr.indexOf(91));//-1

//start 为开始位置,从start开始遍历,返回它在数组中总的位置
var arr = [5,3,5,6,8,5,2];
console.log(arr.indexOf(5,4));//5
console.log(arr.indexOf(5,6));//-1

  • 数组去重:
    var arr = [3,5,6,2,1,8,5,4,2,"2"];
    
    var newArr = [];
    for(var i = 0;i<arr.length; i++){
    	if(newArr.indexOf(arr[i]) == -1){
    		newArr.push(arr[i]);
    	}
    }
    console.log(newArr);//(8) [3, 5, 6, 2, 1, 8, 4, "2"]
    

(2)lastIndexOf(),从后面往前找,但索引值不变(没有就返回 -1);

var arr = [2, 5, 4, 8, "2", "4", 2, 6, 12, 2, 4];
console.log(arr.lastIndexOf(2));  //9
console.log(arr.lastIndexOf("3"));//-1
2.3 ES5新增的遍历数组的方法forEach()map()filter()some()every()

(1)forEach( function(val, index, arr){ }),专门用来 遍历数组;

var arr = [8,7,5,7,4,6];
arr.forEach(function(val,index,arr){
	console.log(val);//8 7 5 7 4 6
	console.log(index);//0 1 2 3 4 5
	console.log(arr);//(6) [8, 7, 5, 7, 4, 6]
})

(2)map( function(val, index, arr){ }),返回原数组长度的数组 ;

不仅可以实现 forEach 的遍历,还可以有返回值常用 map() + return来修改原数组的值,返回一个新数组,不影响原数组。

var arr = [8,7,5,7,4,6];
//1. 没有 return 时,效果与forEach相同
arr.map(function(val,index,arr){
	console.log(val);//8 7 5 7 4 6
	console.log(index);//0 1 2 3 4 5
	console.log(arr);//(6) [8, 7, 5, 7, 4, 6]
})

//2. map() 中使用 return 的用法
var a = arr.map(function(val,index,arr){
	return "hello";
})
console.log(a);//(6) ["hello", "hello", "hello", "hello", "hello", "hello"]

//3. 在map()中使用return,map()可以修改原数组的值,但不会影响到原数组
var b = arr.map(function(val,index,arr){
	return val+10;
})
console.log(b);//(6) [18, 17, 15, 17, 14, 16]
console.log(arr);//(6) [8, 7, 5, 7, 4, 6]

(3)filter( function(val, index, arr){ }),过滤,不改变原数组。

将函数执行一遍,只有在 布尔值为 true 时才返回符合条件的 数据。效果与 map() 类似。

var arr = [8,7,5,7,4,5,6];
//没有 return 时,效果与forEach相同
arr.filter(function (val, index, arr){
	console.log(val);//8 7 5 7 4 5 6
	console.log(index);//0 1 2 3 4 5 6
	console.log(arr);//(7) [8, 7, 5, 7, 4, 5, 6]
})

//2. filter() 中 return 的是一个布尔值,过滤出条件为 true 的值
var b = arr.filter( function(val, index,arr){
	return "hello";//字符为true,空字符为false
})
console.log(b);//(7) [8, 7, 5, 7, 4, 5, 6]

//3. 过滤出符合条件的数据
var a = arr.filter( function (val ,index, arr){
	return val > 6;
})
console.log(a); //(3) [8, 7, 7]

(4)some( function(val){ }),判断数组是否存在某个属性值/对象(indexOf()有局限性);
indexOf()有局限性,遍历数组时,如果数组中某条数据符合判断条件,则返回值为 ture

var arr = [
  {name: "lili", age: 18},
  {name: "hxl", age: 19}
];
var res = arr.some(function(item){
  console.log(item);
  //打印结果:{name: "lili", age: 18}  
  //          {name: "hxl", age: 19}
  
  return item.name === 'hxl'; //判断条件
});
console.log(res);  //true 存在hxl

(5)every( function(val){ }),遍历数组时,每条数据都满足判断条件时,返回 ture,只要有一条不满足则返回false。IE浏览器不支持。

var arr = [
  {name: "lili", age: 18},
  {name: "hxl", age: 19}
];
var res = arr.some(function(item){
  console.log(item);
  //打印结果:{name: "lili", age: 18}  
  //          {name: "hxl", age: 19}
  
  return item.age === '18'; //判断条件
});
console.log(res);  //false 有一条数据不满足条件


三、字符串的方法(偏ES5)

字符串可以是插入到引号中的任何字符。你可以使用单引号或双引号
创建字符串的方式:
(1)字面量方式创建:var str = "hello";
(2)构造函数方式创建:var str = new String("hello")

字符串像数组一样也有长度,意味着它可以像数组一样通过索引来获取字符

var str = "I love you";
console.log(str.length);  //10
conosle.log(str[0]);      //I
3.1 判断字符串中是否存在某个字符:indexOf()lastIndexOf()

indexOf(data, start)lastIndexOf(data, start)用法与在数组中一样。字符在字符串中存在返回索引,不存在就返回 -1

var str = "hello world";
console.log( str.indexOf("o") );  //4
console.log( str.lastIndexOf("o") );  //7
3.2 返回在指定位置的字符或字符编码:charAt(index)charCodeAt()

(1)charAt(index),返回在指定位置的字符;

var str = "hello world";
console.log(str.charAt(10));//d

(2)charCodeAt(),返回指定的位置的字符的 Unicode 编码;

var str="abc"
 console.log(str.charCodeAt(1))//98,98是b的十进制编码
3.3 截取:slice()substr()substring()

(1)slice(start, end),截取从 start 到 end 位置的字符串,含前不含后; 返回新的字符串,不会改变原字符串。slice() 更多用于数组。

  • start,必须值(数值形式),字符串的起始下标,若是负值就会从字符串末尾开始算,从 -1 开始。
  • end,可选,截取到字符串的 end 位置。如果不写,就会截取到 start 位置-字符串末尾。
var str = "hello world";
console.log(str.slice(2,7));//llo w

(2)substr(start, length),从 start 位置开始截取(包括 start 位置的字符),截取长度为 length 的字符串出来。返回新的字符串,不会改变原字符串。

  • start,必须值(数值形式),字符串的起始下标,若是负值就会从字符串末尾开始算,从 -1 开始。
  • length,可选,截取到的字符串的长度。如果不写,就会截取到 start 位置-字符串末尾。
var str = "hello world";
console.log(str.substr(2));    //llo world
console.log(str.substr(1,6));  //ello w
console.log(str);              //hello world

(3)substring(start, end),截取从 start 到 end 位置的字符串,含前不含后;返回新的字符串,不会改变原字符串。与 slice() 作用和用法相同。

var str = "hello world";
console.log(str.substring(2));    //llo world
console.log(str.substring(2,8));  //llo wo
console.log(str);                 //hello world
3.4 字符大小写转换:toLowerCase()toUpperCase()

(1)toLowerCase(),把字符串转换为小写;

var str = "Hello ShangHai!I love YOU.";
console.log(str.toLowerCase());    //hello shanghai!i love you.

(2)toUpperCase(),把字符串转换为大写;

var str = "Hello ShangHai!I love YOU.";
console.log(str.toUpperCase());    //HELLO SHANGHAI!I LOVE YOU.
3.5 字符中有关正则的方法:match()replace()search()

(1)match(),在字符串内检索指定的值(类似indexOf(),不过返回的是值而非索引),或找到一个或多个正则表达式的匹配。

var str="1 abc 2 def 3"
console.log(str.match(/\d+/g));  //123

(2)replace(oldval, newVal),替换(一次只能替换一个)

var str = "hello world";
console.log(str.replace("o","啊"));//hell啊 world
  • 若想替换多个
    //方法1
    var str = "hello world";
    console.log(str.replace("o","啊").replace("o","啊"));//hell啊 w啊rld
    
    //方法二
    for(var i = 0; i< str.length; i++){
    	str = str.replace("o","哦");
    }
    console.log(str);//hell哦 w哦rld
    
  • 敏感词过滤(上面这种方法耗内存,最好用正则)
    var msg = ['fuck',"滚",'tm','nnd','sb','sx'];//敏感词库
    var str = "你tm真让人无语";//要说的话
    for(var i=0;i<str.length;i++){
    	msg.forEach( function (val,index){
    		str = str.replace(val,"**");
    	})
    }
    console.log(str);//你**真让人无语
    

(3)search(),返回指定字符串的索引,如果没有就返回 -1

var str="abc DEF!"
console.log(str.search(/DEF/))//4
3.6 字符转成数组:split()
var str = "2018/7/30";
console.log(str.split());//["2018/7/30"]
console.log(str.split(""));//(9) ["2", "0", "1", "8", "/", "7", "/", "3", "0"]
console.log(str.split("/"));//(3) ["2018", "7", "30"]
3.7 合并字符串:concat()
var a = "abc";  
var b ="def";  
console.log(a.concat(b));//abcdef
3.8 去除字符串首尾的空格:trim()
var str = '  555  666 ';
console.log(str.trim());  //555  666


四、字符编码

计算机中储存的信息都是用二进制数表示的;我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果。

  • 按照何种规则将字符存储在计算机中,如’a’用什么表示,称为"编码";反之,将存储在计算机中的二进制数解析显示出来,称为"解码",同密码学中的加密和解密
  • 在解码过程中,如果使用了错误的解码规则,则导致’a’解析成’b’或者乱码。
  • 字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
  • 字符编码(Character Encoding):是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。即在符号集合与数字系统之间建立对应关系,它是信息处理的一项基本技术。

常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。

charCodeAt();,字符转ASCII码(十进制),中文转十进制;
charCodeAt(n);,返回指定位置的字符的Unicode;
String.fromCharCode(n)

  • n 为 ASCII码,ASCII码 转 字符;
  • n 为 十进制,十进制 转 中文;
  • n 为 十六进制,十六进制 转 中文;
4.1 ASCII:

ASCII:美国信息交换标准码,主要用于显示现代英语。
ASCII字符集:主要包括控制字符(回车键、退格、换行键等);可显示字符(英文大小写字符、阿拉伯数字和西文符号)。
ASCII编码:将 ASCII字符集 转换为计算机可以接受的数字系统的数的规则。
在这里插入图片描述
(1)字符转ASCII码(十进制):charCodeAt();
(2)ASCII码 转 字符: String.fromCharCode(ASCII码)

console.log('0'.charCodeAt());//48
console.log('1'.charCodeAt());//57
console.log('A'.charCodeAt());//65
console.log('a'.charCodeAt());//97

console.log(String.fromCharCode(97));//a
4.2 Unicode编码:

万国码、统一码、单一码。将世界上所有的符号都纳入其中,无论是英文、日文、还是中文等,大家都使用这个编码表,就不会出现编码不匹配现象。

可以这样理解:Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三种字符编码方案。

(1)中文转十进制: charCodeAt();
(2)十进制转中文:String.fromCharCode(十进制);
(3)十六进制转中文: String.fromCharCode('0x十六进制');
(4)返回指定位置的字符的Unicode: charCodeAt(n);

var str = "贺";
console.log(str.charCodeAt()); //36154  十进制
var num = 36154;
console.log(num.toString(16)); //8D3A 十进制转十六进制,这个十六进制就是“贺”的unicode编码
console.log("\u8D3A"); //贺   8D3A是36154的十六进制,\u表示是Unicode编码
console.log(String.fromCharCode(36154)); //贺
console.log(String.fromCharCode('0x8D3A')); //贺

UTF-8:只有网页上使用。

4.3 GBK:只有中文


五、ES5对象的序列化和反序列化

1. json 转字符JSON.stringify(str); 且转换后是严格写法的 json 格式字符串;
2. 字符转 jsonJSON.parse(str); 要求 str 必须是一个严格写法的 json 格式字符串。否则会报错;
在这里插入图片描述

var json = {"name":"admin",age:18};
var str = JSON.stringify(json)
console.log(typeof json);//object
console.log(str);//{"name":"admin","age":18}
console.log(typeof str);//string

console.log(JSON.parse(str));//{name: "admin", age: 18}
  • 注意cookie 存值的时候,值最好是字符,若是对象,会被转换成 [object Object]。所以要存对象时,首先要把它变成字符串格式


六、ES5函数的方法:bind

ES5函数的方法:bind

作用:
(1)改变原函数的 this 的指向,指向 bind 中的第一个参数;
(2)bind 也是函数的方法。可以让原本没有某个功能的对象,具有这个功能。
bind 返回的是一个新的函数,你必须调用它才会被执行。
(3)bind 的第二个参数往后所有参数,会当成原函数的参数,把原函数挤到后面,并和原本的参数一起被存到arguments中。

6.1 bind 的作用

(1)改变原函数的 this 的指向,指向 bind 中的第一个参数** ,并且把指向的内容强行修改为对象。

var obj =  {
	name:"admin",
	show:function(){
		document.onclick = function(){
			console.log(this);
		}.bind(obj);
	}
}
obj.show();  //也可以将bind写在调用方法的后面 obj.show.bind(obj)();
//原本指向 document,打印: #document
//.bind(obj)后this指向 obj,打印: {name: "admin", show: ƒ}

把指向的内容强行修改为对象。

var obj =  {
	name:"admin",
	show:function(){
		document.onclick = function(){
			console.log(this);
		}.bind("hello");
	}
}
obj.show(); //String {"hello"}   

(2)bind 也是函数的方法。可以让原本没有某个功能的对象,具有这个功能。

var a = {
	name : "小明",
	show: function(){
		console.log(this.name+"在踢球");
	}
}
var b = {
	name: "小黄"
}
a.show();//小明在踢球
a.show.bind(b)();//小黄在踢球
//a.show().bind(b)//小明在踢球    a.show()就已经执行了a中的函数show
a.show().bind(b)();//报错

在这里插入图片描述

(3)bind 的第二个参数往后所有参数,会当成原函数的参数,把原函数中的参数往后面挤,多下来的参数和原本的参数一起被存到 arguments 中。

var obj = {
	name: 'admin',
	show: function(a,b){
		console.log(a,b);
		console.log(arguments);
		console.log(this);
	}
}
obj.show.bind("hello")("10",20);
console.log("----------------")
obj.show.bind("hello","world")("10",20);
console.log("----------------")
obj.show.bind("hello","world","js")("10",20);

在这里插入图片描述

6.2 利用 bind 封装事件委托

原来的事件委托 this 指向的父元素(用 target),利用 bind 改为操作哪个元素,this 就指向这个元素。

//使用: 父元素.onclick = eveEntrust(子元素,function(){//操作})
oul.onclick = eveEntrust("LI",function(){
  console.log(this);
})

function eveEntrust(child,callback){
  return function(eve){
    var e = eve || winodw.event;
    var target = e.target || e.srcElement;
    if(target.nodeName == child){
      //callback(target);//此时的this指向window;若用这种方法,则使用时函数要含参数来接收这个 target
      callback.bind(target)();
    }
  }
}
  • 最终版:
    varali = oul.children;
    //使用: 父元素.onclick = eveEntrust(所有子元素DOM,function(){//操作})
    oul.onclick = eveEnt(ali,function(){
      console.log(this)
    })
    
    function eveEnt(child,callback){
      return function(eve){
        var e = eve || window.event;
        var target = e.target || e.srcElemt;
        for(var i=0; i<child.length; i++){
          if(target == child[i]){
            callback.bind(target)();
          }
        }
      }
    }
    
6.3 apply 查找数组中的最小/大值

当min接收多个参数时,在min函数内部,肯定要对这些参数进行处理和比较。当传数组时,只有一个数据,没办法对数组内部的数据逐个比较,所以 Math.min(arr) 的返回结果是NaN

var arr = [23,45,74,73,42,65,78];
var min = Math.min.apply(null, arr);
console.log(min); //23
  • 按照前面介绍的,数组 arr 作为参数被 Math.min 的方法解析,其实就相当于Math.min.call(null, 23,45,74,73,42,65,78)
  • null 作为第一个参数,是用来改变 this指向,nullundefined 时,将是JS执行环境的全局变量。
6.4 bind、call、apply的区别
序号bind、call、apply的相似之处
1都是用来改变函数的 this 对象的指向的。
2第一个参数都是 this 要指向的对象。
3都可以利用后续参数传参。
4三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等。

三者的不同:
(1)bind 返回的是一个新的函数,必须调要用它才会被执行。
(2)call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 对象中的方法.call(this指向,'参数1', ... ,'参数n' )bind 除了返回是函数以外,它的参数和 call 一样。
(3)apply 的所有参数都必须放在一个数组里面传进去 对象中的方法.apply(this指向,['参数1', ... ,'参数n'])

一个参数:

var a = {
	name : "小明",
	show: function(){
		console.log(this.name+"在踢球");
	}
}
var b = {
	name: "小黄"
}
a.show.bind(b)();//小黄在踢球
a.show.call(b);//小黄在踢球
a.show.apply(b);//小黄在踢球

多个参数:

var a = {
	name : "小明",
	age: "18",
	show: function(from,to){
		console.log(this.name+"的年龄是:"+this.age+",来自:"+from+",要去往:"+to);
	}
}
var b = {
	name: "小黄",
	age: "19",
}
a.show.bind(b,"成都","上海")(); //小黄的年龄是:19,来自:成都,要去往:上海
a.show.bind(b)("成都","上海"); //小黄的年龄是:19,来自:成都,要去往:上海
a.show.bind(b,"成都")("上海"); //小黄的年龄是:19,来自:成都,要去往:上海

a.show.call(b,"成都","上海"); //小黄的年龄是:19,来自:成都,要去往:上海
a.show.apply(b,["成都","上海"]); //小黄的年龄是:19,来自:成都,要去往:上海

上一篇——js(一)js基础、程序结构、函数、对象和构造函数、数组、this
下一篇——js(三)事件、cookie、正则、ES6

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值