ECMAScript
客户端脚本语言的标准
基本语法
与html结合方式
-
内部JS:
-
标签体内容就是js代码
<script text="text/javascript"> // 内容 </script>
-
-
外部JS:
-
通过src属性引入外部的js文件
<script text="text/javascript" src="location"> // 内容 </script>
-
注意:
- 可以定义在html页面的任何地方。但是定义的位置会影响执行顺序;
- 可以定义多个;
- 同一个标签不能同时引入外部 同时有内部的,这样的话只有外部的好使。
注释
- 单行注释://注释内容
- 多行注释:/注释内容/
数据类型
原始数据类型(基本数据类型)
number
数字类型,整数 / 小数 / NaN(not a number 一个不是数字的数字类型)
toFixed(x)
小数点后保留 x 位小数
问题 bug:
-
浮点数精度不准
-
小数点前 以及 小数点后 位数大于 16 会出现精度问题
console.log(1000000000000001 + 1000000000000001) // 2000000000000002 console.log(10000000000000001 + 10000000000000001) // 20000000000000000 console.log(1.000000000000001 + 1.000000000000001) // 2.000000000000002 console.log(1.0000000000000001 + 1.0000000000000001) // 2
string
字符串类型,字符串 “abc” “a” ‘abc’
boolean
布尔类型,true 和 false
- null:一个对象为空的占位符
- undefined:未定义。如果一个变量没有给初始化值,则会被默认赋值为undefined
存放在 栈 里,规则 先进后出
引用数据类型
-
Array:数组。
-
Object:对象。
-
function:函数。
…
存放在 堆 里,拷贝的是地址
变量
概念
一小块存储数据的内存空间
强弱类型
Java语言是强类型语言,而JavaScript是弱类型语言。
- 强类型:在开辟变量存储空间时,定义了空间将来存储的数据的数据类型。只能存储固定类型的数据
- 弱类型:在开辟变量存储空间时,不定义空间将来的存储数据类型,可以存放任意类型的数据。
全局&局部变量
访问规则
- 里面的可以访问到外面的,外面的不能访问里面的
定义语法
var 变量名 = 初始化值;
// 定义多个遍历并赋值
var a = 10,
b = 20,
c = 30,
d = 40,
e;
document.write(a,b,c,d,e);
命名规则
- 变量名必须以英文字母、_ 、$ 开头;
- 变量名可以包括英文字母、_ 、$ 、数字;
- 不可以用系统的关键字、保留字作为变量名。
typeof 操作符
获取变量的类型。
number string boolean object undefined function
console.log(typeof(123)); // number
console.log(typeof("123")); // string
console.log(typeof(true)); // boolean
用法:
typeof(值)
typeof 值
注:
-
null、array 运算后得到的是object
-
typeof() 返回的值是字符串类型
特殊:
变量不定义就使用必定会报错,只有一种情况下不会
自定义 type 方法:区分所有类别
function type(target) {
var ret = typeof(target);
var template = {
"[object Array]" : "array",
"[object Object]" : "object",
"[object Number]" : "number - object",
"[object Boolean]" : "boolean - object",
"[object String]" : "string - object"
}
if (target === null) {
return "null";
} else if (ret == "object") {
var str = Object.prototype.toString.call(target);
return template[str];
} else {
return ret;
}
}
类型转换
隐式类型转换
isNaN()
console.log(isNaN(NaN)); // true
console.log(isNaN(123)); // false
console.log(isNaN("123")); // false
console.log(isNaN("abc")); // true
console.log(isNaN(null)); // false
console.log(isNaN(undefined)); // true
isNaN() 之前会先 Number()
模拟 isNaN() 方法:
function myIsNaN(num) {
var ret = Number(num);
ret += "";
if (ret == "NaN") {
return true;
} else {
return false;
}
}
++ – + -
(自增 自减 正负号)
var a = "123";
a ++; // 124
var a = +"123"; // +123
var b = +"abc"; // NaN
+
(加号)
两侧没有字符串,则正常数字相加,调用 Number() 方法将不是 number 的隐式转换
当加号两侧至少有一侧是字符串时,会调用 String() 方法把两侧均转换为字符串
当加号左侧是引用类型值时,调用的是 String() 方法隐式转换
[] + 1; // --> String([]) + 1 --> "1"
[] + ""; // ""
{} + 1; // 1
但引用值的隐式类型转换不用知道,规则较多。
- * / %
(运算符号)
调用 Number() 方法
var num = "2" * "1"; // number : 2
var num = "a" * "1"; // number : NaN
&& || !
判断调用 Boolean() 方法
< > …
(比较符号)
var a = 3 > "2"; // boolean: true
var a = "3" > "2"; // 会比较对应的 ASCII码 值
特殊
undefined > 0; // false 不转换,系统规定 undefined 和 null 不能和数进行比较
null > 0; // false
== !=
调用 Boolean() 方法
引用值比较的是地址:
{} == {}; // false
[] == []; // false
var obj = {};
var obj1 = obj;
obj == obj1; // true
obj === obj1; // true
特殊:
undefined == null; // true
NaN == NaN; // false
显式类型转换
Number()
把里面的东西转换为数字型
null false => 0
undefined => NaN
parseInt()
把里面的数转换为整数
注:看到非数字位截止
parseInt("123"); // 123
parseInt("123abc"); // 123
// 用途
// 把像素值从 100px 中取出来
parseInt(值, radix)
radix: 2 - 36
后面的第二个参数表示此数所表示的进制
后面填 0
- 有的浏览器是 原样转换整型输出
- 有的是输出 NaN
parseFloat()
注:看到除了第一个 . 的非数字位截止
Boolean()
toString()
语法:
var demo = 10
var str = demo.toString(); // "10
// 转换进制
var num = demo.toString(8); // 12
注:undefined 和 null 不能用 toSting() 方法
例子:
二进制 转 十六进制
var num = 10000;
var test = parseInt(num, 2);
console.log(test.toString(16)); // aa
不发生类型转换
=== !==
数值 和 类型 均相等才可
1 === 1; // true
1 === "1"; // false
1 !== "1"; // true
1 !== 1; // false
特殊:
练习
var str = false + 1;
document.write(str); // 1
var demo = false == 1;
document.write(demo); // false
if (typeof(a) && -true + (+undefined) + "") {
document.write('基础扎实!');
}
if (11 + "11" * 2 == 33) {
document.write('基础扎实!');
}
!!" " + !!"" - !!false || document.write('你觉得能打印,你就是🐖');
运算符
一元运算符
只有一个运算数的运算符
++,-- , +(正号)
- ++ --: 自增(自减)
- ++(–) 在前,先自增(自减),再运算
- ++(–) 在后,先运算,再自增(自减)
- +(-):正负号
注意:在JS中,如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算数进行类型转换
- 其他类型转number:
- string转number:按照字面值转换。如果字面值不是数字,则转为NaN(不是数字的数字)
- boolean转number :true转为1,false转为0
算数运算符
+ - * / %
注:
- 1/0 会得 Infinity(无穷)
- 1/0 会得 -Infinity
- 0/0 会得 NaN
赋值运算符
= += -= *= /= %=
比较运算符
< >= <= == ===(全等于)
比较方式:
-
类型相同:直接比较
字符串:按照字典顺序比较。按位逐一比较,直到得出大小为止。即 ASCII码 值
-
类型不同:先进行类型转换,再比较
===:全等于。在比较之前,先判断类型,如果类型不一样,则直接返回false
逻辑运算符
&& || !
-
&&(与):先看第一个表达式转化为 boolean 值是否为真,结果为真,则依次往后看每个表达式转换为boolean值的结果,直到碰到结果为 false 的表达式,返回该表达式的值。
用法:(短路语句)
var data = ...; // data && 执行一个语句,会用到data; data && fn(data);
-
||(或):碰到表达式的结果 boolean值为真则返回该表达式的值
用法:(兼容)
div.onclick = function (e) { // 兼容 IE 浏览器 var event = e || window.event; }
-
! (非):将表达式的值转换为 boolean值 再取反,返回该 boolean值。
var a = !!""; // !! 可以让一个值转换为 boolean值
注意:
undefined、null、NaN、""、0、false ==> false
除了以上六个值以外,其他的转换为 boolean 类型均为 true
练习:
(window.foo || (window.foo = 'bar'));
// window.foo = 'bar'
// 先读小括号内的,即先赋值
三元运算符
语法:
判断表达式的值,如果是 true 则取值1,如果是 false 则取值2;
逗号运算符
会将后面的结果返回出去
var a = (1 - 1, 1 + 1);
a --> 2
括号运算符
-
优先运算
将里面的内容变为表达式
(function () {})
函数声明失效,变为表达式 -
立即执行
(function () {})()
流程控制语句
-
if…else…
if(判断语句) { 条件体 }
-
switch:
-
在java中,switch语句可以接受的数据类型: byte int shor char,枚举(1.5) ,String(1.7)
-
在JS中,switch语句可以接受任意的原始数据类型
switch () { case 判断条件1: 执行语句1; break; case 判断条件2: 执行语句2; break; case 判断条件3: 执行语句3; break; ... default: break; }
-
while
底层机制就是 for 循环:for 循环括号内两边不写语句就是 while 循环:
for (;条件语句;) {}
while(条件语句) { 循环语句 }
-
do…while
先执行一次,再判断条件语句
do { 循环体 } while (条件语句)
-
for
-
break
跳出循环或者 switch
-
continue
终止本次循环进行下次循环
JS特殊语法
- 语句以 ; 结尾,如果一行只有一条语句则 ; 可以省略 (不建议)
- 变量的定义使用 var 关键字,也可以不使用
- 用:定义的变量是局部变量
- 不用:定义的变量是全局变量(不建议)
- 练习:99乘法表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>99乘法表</title>
<style>
td{
border: 1px solid;
}
</style>
<script>
document.write("<table align='center'>");
//1.完成基本的for循环嵌套,展示乘法表
for (var i = 1; i <= 9 ; i++) {
document.write("<tr>");
for (var j = 1; j <=i ; j++) {
document.write("<td>");
//输出 1 * 1 = 1
document.write(i + " * " + j + " = " + ( i*j) +" ");
document.write("</td>");
}
/*//输出换行
document.write("<br>");*/
document.write("</tr>");
}
//2.完成表格嵌套
document.write("</table>");
</script>
</head>
<body>
</body>
</html>
基本对象
包装类
使用包装类对象创建的以下三种对象,依然还带有原本的数据类型的特点,不同在于可以有属性和方法
但是 undefined 和 null 不可以设置属性
Number:数字对象
String:字符串对象
Boolean:布尔对象
详解
原始数据类型不能有自己的属性和方法
自定义属性
但下面这个却不报错:
var num = 4;
num.len = 3; // 不报错
console.log(num.len) // undefined
原因:(包装类)
var num = 4;
num.len = 3; // 不报错
// new Number(4).len = 3;
// delete
// new Number(4).len --> undefined
console.log(num.len) // undefined
length问题
在数组中:
var arr = [1, 2, 3, 4, 5];
// arr.length --> 5
arr.length = 2
// arr.length --> 2
// arr --> [1, 2]
但是,在字符串中
var str = 'abcd';
// str.length --> 4
str.length = 2;
// new String('abcd').length = 2;
// delete
console.log(str); // abcd
// new String('abcd').length
console.log(str.length); // 4
字符串对象 本身就有 length属性,调用时是从包装类对象中返回的属性值
例题
var str = 'abc';
str += 1;
var test = typeof str; // test --> 'string'
if (test.length == 6) {
test.sign = 'typeof的返回结果可能为String';
// new String(test).sign = 'xxx';
}
// new String(test).sign
console.log(test.sign);
Function:函数对象
高内聚,弱耦合
创建
var fn = new Function(形式参数列表,方法体);//忘掉吧
// 函数声明
function 方法名称(形式参数列表) {
方法体
}
// 命名函数表达式
var 方法名 = function abc() {
方法体
}
// 匿名函数表达式 --- 函数表达式
var 方法名 = function() {
方法体
}
参数
// 形式参数(形参)
function sum(a, b) {
var c = a + b;
document.write(c);
}
// 实际参数(实参)
sum(1, 2); // 3
参数不限制位数
arguments
表示实参列表,也有一些属性
-
arguments.length 实参个数
-
arguments.callee 指向这个函数自身引用 --> 即函数本身
var num = (function (n) { if (n == 1) { return 1; } return n * arguments.callee(n - 1); }(100))
函数名.length 形参个数
function sum(a) {
// arguments -- [11,2,3] 实参列表
console.log(arguments); // [11,2,3]
console.log(arguments.length); // 3
// 函数名.length -- 形参长度
concole.log(sum.length); // 1
}
sum(11, 2,3)
例子:
// 求不定参数个数的和
function sum() {
var result = 0
for (let i = 0; i < arguments.length; i++) {
result += arguments[i];
}
document.write(result);
}
sum(1,3);
arguments里面的值 和 形参的值 之间有映射关系,但只是在形参和实参对应时才生效
function sum(a, b) {
// arguments --> [1]
a = 2;
console.log(arguments[0]); // 2
arguments[0] = 3;
console.log(a); // 3
b = 2;
console.log(arguments[1]); // undefined
}
sum(1);
caller
函数的一个属性:表示被调用的环境
function test() {
demo();
}
function demo() {
demo,caller; // --> test --> function test() {demo();}
}
test();
不怎么用,但会和 arguments.callee 一块出现做区分
特点
- 方法定义时,形参的类型不用写,返回值类型也不写
- 方法时一个对象,如果定义名称相同的方法,会覆盖
- 在JS中,方法的调用只与方法的名称有关,和参数列表无关
- 在方法声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数
调用
连续调用
模拟 jQuery 连续调用
var deng = {
smoke : function () {
console.log('Somking...');
return this;
},
drink : function () {
console.log('Drinking...');
return this;
},
perm : function () {
console.log('Perming...');
return this;
}
}
deng.smoke().drink().perm();
结束条件和返回值
- return 语句后的内容将不再执行,终止函数
- 返回值
function myNumber(target) {
return +target;
}
var num = myNumber('123');
console.log(typeof(num) + " " + num); // number 123
练习
求阶乘
// 求阶乘方法
// n! = n * (n-1)!
function mul(n) {
if (n == 1 || n == 0) {
return 1
}
return n * mul(n - 1);
}
var n = parseInt(prompt('input'));
mul(n);
// 递归
/*
mul(5);
5 * mul(4);
5 * 4 * mul(3);
5 * 4 * 3 * mul(2);
5 * 4 * 3 * 2 * 1;
*/
斐波那契数列
// 斐波那契数列
// fb(n) == fb(n - 1) + fb(n - 2)
function fb(n) {
if (n == 2 || n == 1) {
return 1;
}
return fb(n - 1) + fb(n - 2);
}
原型 prototype
原型是 function 对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该圆心的属性和方法。原型也是对象。
Person.prototype.LastName = "Agoni";
function Person() {
}
var person = new Person();
var person1 = new Person();
// person.LastName --> "Agoni"
// person1.LastName --> "Agoni"
对象中固定不变的属性(公有的内容)可以提取出来放到原型中,避免代码多次执行造成冗余。
增删改查
删
经过了 var 给 window 上增加的属性为不可配置性属性,delete无法删除。
增改查
设置属性(可以多个一起设置)
Person.prototype = {
height: 1400,
lang, 4900,
carName: "BMW"
}
和 Person.prototype.name = ""
的区别:
- 上面的那一种是重新放一个空间,如之前已设置过且已经生成了对象,则
__proto__
所指向的还是原先的那个空间; - 下面的是在原先的空间中设置或修改属性,使得
__proto__
的访问数据变更
构造器 constructor
function Car() {}
var car = new Car();
// car.constructor --> funciton Car() {}
function Person() {}
Car.prototype = {
constructor : Person
}
// car.constructor --> function Person() {}
__proto__
隐式属性 __proto__
内就放着原型,在控制台展开可以查看
原理:
Person.prototype.name = "abc";
funciton Person() {
// var this = {
// __proto__ : Person.prototype
// }
}
var person = new Person();
原型也可以改变:
// 代码接上一部分
var obj = {
name: "sunny"
}
var person = new Person();
// person.name --> "abc"
Person.__proto__ = obj;
// person.name --> "sunny"
原型链
Grand.prototype.lastName = "agoni";
funciton Grand() {
}
var grand = new Grand();
Father.prototype = grand;
function Father() {
this.name = "Lay"
}
var father = new Father();
Son.prototype = fatehr;
function Son() {
this.hobbit = "smoke"
}
var son = new Son();
// son.hobbit --> "smoke"
// son.name --> "Lay"
// son.lastName --> "Agoni"
查找属性,依照 son --> father --> grand
顺序依次查找,这个链就叫 原型链。
链顶并不是最末的:
Object.prototype
是绝大多数对象的最终原型
// Grand.prototype.__proto__ --> Object.prototype
// son.toString() --> function toString() { [native code] } // 最终终端的方法
// Object.prototype.__proto__ --> null
Object.prototype 里面没有 __proto__ 了
Object.create()
括号内填原型:只能是 对象 或 null
Person.prototype.name = "sunny";
function Person() {
}
var person = Object.create(Person.prototype)
特殊点:
原型最终不会指向 Object.prototype
var obj = Object.create(null);
// obj.toString() --> 访问不到,报错
语法:
Object.create(prototype, definedProperty<特性>)
方法重写
Person.prototype = {
toString : function () {
return 'hehe';
}
}
function Person() {
}
var person = new Person();
// person.toString(); --> "hehe"
发生截断,不会访问到终端 Object.prototype 的 toSting() 方法
Number Array Boolean String 都对 toSting() 方法进行了重写
document.write 原理
会隐式调用 toSting() 方法
var obj = Object.create(null);
document.write(obj); // 报错,因为自己创建的对象值为 null 且 Object.create() 创建的没有原型链,没有 toString() 方法,所以报错
obj.toStirng = function () {
return 'AgoniLay';
}
document.write(obj); // AgoniLay --> 调用了 AgoniLay 方法
call/apply
call()
call 带参数
根本作用:改变 tihs 指向
function Person(name, age) {
this.name = name;
this.age = age;
}
var person = new Person('deng', 100);
var obj = {
}
// 第一个参数指 this 的指向,之后的依次代表 实参 对应 形参
Person.call(obj, 'agoni', 19);
// obj --> {name: 'agoni', age: 19}
使用实例:
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name, age, sex, tel, grade) {
Person.call(this, name, age, sex);
this.tel = tel;
this.grade = grade;
}
var student = new Student('sunny', 123, 'male', 1309, 2017);
function Wheel(wheelSize, style) {
this.style = style;
this.wheelSize = wheelSize;
}
function Sit(c, sitColor) {
this.c = c;
this.sitColor = sitColor;
}
function Model(height, width, len) {
this.height = height;
this.width = width;
this.len = len;
}
function Car(wheelSize, style, c, sitColor, height, width, len) {
Wheel.call(this, wheelSize, style);
Sit.call(this, c, sitColor);
Model.call(this, height, width, len);
}
var car = new Car(100, '花里胡哨', '真皮', 'red', 1800, 1900, 4900);
// car {style: "花里胡哨", wheelSize: 100, c: "真皮", sitColor: "red", height: 1800, …}
apply()
和 call() 区别:
- 传参列表不同:apply 第一个参数还是 this 所指对象,第二个参数是一个数组,数组里面是所有的实参
- call 需要把实参按照形参的个数传进去
- apply 需要传一个 arguments
function Car(wheelSize, style, c, sitColor, height, width, len) {
Wheel.apply(this, [wheelSize, style]);
Sit.call(this, [c, sitColor]);
Model.call(this, [height, width, len]);
}
继承 --> 圣杯模式
-
传统形式 --> 原型链
- 过多的继承了没用的属性
-
借用构造函数 call()/apply()
- 不能继承借用构造函数的原型
- 每次构造函数都要多走一个函数(视觉上减少代码,但多走了方法)
-
共享原型
son.prototype = father.prototype
Father.prototype.lastName = "AgoniLay" function Father() { } function Son() { } funciton inherit(Target, Origin) { Target.prototype = Origin.prototype; } // 先继承,后用 inherit(Son, Father); var son = new Son(); // son.lastName --> "AgoniLay" // father.lastName --> "AgoniLay" Son.prototype.sex = "male"; // 添加后,son 和 father 都有了这个属性 // son.sex --> "male" // father.sex --> "male"
-
圣杯模式 *
// 通俗写法 function inherit(Target, Origin) { function F() {}; // 以下两行顺序不能颠倒 F.prototype = Origin.prototype; Target.prototype = new F(); // 优化 Target.prototype.constuctor = Target; Target.prototype.uber = Origin.prototype; } Father.prototype.lastName = "AgoniLay" function Father() { } function Son() { } inherit(Son, Father); var son = new Son(); var father = new Father(); // father.lastName --> "AgoniLay" // son.lastName --> "AgoniLay" Son.prototype.sex = "male"; // son.sex --> "male" // father.sex --> undifined
// 雅虎的 var inherit = (function () { var F = function () {}; // 闭包应用 -- 私有化变量 return function (Target, Origin) { F.prototype = Origin.prototype; Target.prototype = new F(); Target.prototype.constructor = Target; Target.prototype.uber = Origin.prototype; } }());
Array:数组对象
创建
-
var arr = [];
数组字面量 – 推荐使用var arr = [1,2,3]; var arr = [,,]; // [undefined * 2] var arr = [1,,2]; // [1, undefined, 2] --> 稀松数组
-
var arr = new Array();
和 数组字面量 区别:
// 只传一个参数,代表数组的长度 var arr = new Array(10); // [undefined * 10] // 但不能只传一个小数 var arr = new Array(10.2); // 报错
读和写
溢出读是 undefined,可以溢出写
var arr[1,2,3];
arr[0] = 2 // [2,2,3]
console.log(arr[10]); // undefined 不会报错
arr[10] = "aa"; // 可以添加 --> [1,2,3,undefined * 7,"aa"]
方法
可以改变原数组的方法开始:只有七个
push()
在数组最后添加数据,不仅可以添加一个,返回值是添加后的数组长度
// 自己写 push() 方法
var arr = [];
Array.prototype.push = function () {
for(var i = 0; i < arguments.length; i ++) {
this[this.length] = arguments[i];
}
return this.length;
}
arr.push(1,2,3); // 3 --> [1,2,3]
但 push 的原理是取决于属性中 length 值,与 length 值有关
pop()
把数组的最后一位剪切出来返回
unshift()
在数组开头添加数据,不仅可以添加一个,返回值是添加后的数组长度
shift()
把数组的第一位剪切出来返回
reverse()
把数组逆转,把原数组返回
splice()
arr.splice(从第几位开始, 截取多少的长度, 在切口处添加新的数据)
返回截取的数组
var arr = [1,1,2,2,3,3];
arr.splice(1,2); // [1,2] --> [1,2,3,3]
var arr = [1,1,2,2,3,3];
arr.splice(1,2,0,0,0) // [1,2] --> [1,0,0,0,2,3,3]
var arr = [1,2,3,4];
// 不截取,只是向中间插入数据 例:向上面数组 3 后面添加一个 0
arr.splice(3,0,0);
var arr = [1,2,3,4];
// 截取的位置可以是负数,表示从倒数开始
arr.splice(-1,1); // [4] --> [1,2,3]
// 实现
splice = function (pos, ...) {
pos += pos > 0 ? 0 : this.length; // -1 + 4 = 3
}
sort() *
在原数组上将原数组内元素升序排列(但并不是数字值的大小)
var arr = [1,3,4,0,-1,9];
arr.sort(); // [-1,0,1,3,4,9]
// 降序
arr.sort().reverse();
为了解决这个问题,sort 留了一个接口让用户自定义排序方式
规则:
- 必须写俩形参
- 看返回值
- 当返回值为负数时,那么前面的数放在前面
- 为正数,那么后面的数在前
- 为 0,不动
var arr = [1,3,5,4,10];
// 传参顺序 1,3 1,5 1,4 1,10 3,5
arr.sort(function (a, b) {
// 函数体
// if (a > b) {
// return 1;
//} else {
// return -1;
//}
// 简化
return a - b; // 升序
// return b - a; // 降序
}) // [1, 3, 4, 5, 10]
运用:
给一个有序的数组,乱序
var arr = [1,2,3,4,5,6,7];
arr.sort(function () {
return Math.random() - 0.5;
})
给一个对象数组,按某一属性排
var cheng = {
name : "cheng",
age : 30,
}
var deng = {
name : "deng",
age : 60,
}
var zhang = {
name : "zhang",
age : 19,
}
var arr = [cheng, deng, zhang];
// 按年龄升序排列
arr.sort(function (a, b) {
return a.age - b.age;
}) // ["zhang", "cheng", "deng"]
按字符串长度排序
var arr = ['as', 'asdad', 's', 'sjdfhakjsdfhlkajsd', 'asdjhajsk'];
arr.sort(function (a, b) {
return a.length - b.length;
}) // ['s', 'as', 'asdad', 'asdjhajsk', 'sjdfhakjsdfhlkajsd']
按字节长度排序
function retBytes(str) {
var num = str.length;
for(var i = 0; i < str.length; i ++) {
if (str.charCodeAt(i) > 255) {
num++;
}
}
return num++;
}
var arr = ['赛的环境asdj', 'asd', '啥的, 爱睡觉的', 'a saa'];
arr.sort(function (a, b) {
return retBytes(a) - retBytes(b);
}) // ["asd", "a saa", "赛的环境asdj", "啥的, 爱睡觉的"]
不改变原数组的方法开始:调用完使用 变量 接收,否则没有意义
concat()
把括号内的数组拼接到前面数组的后面,不在原数组上修改,返回拼接后的数组
toString()
将数组返回为字符串类型的字符串
slice()
arr.slice('从该位开始截取', '截取到该位')
arr.slice(1)
从第 1 位截取,截取到最后,也可以填负数(规则 + length)
arr.slice()
整个截取
join()
将数组中元素按规定连接起来,返回一个字符串
参数可以传所有原始值,但最好传字符串
var arr = [1,2,3];
arr.join("&"); // "1&2&3"
arr.join(); // "1,2,3"
split()
是字符串的方法,是 join() 的可逆方法
var str = "1-2-3-4-5";
str.split("-"); // ["1", "2", "3", "4", "5"]
自定义方法:
unique()
Array.prototype.unique = function (arr) {
var temp = {};
var arr = [];
var len = this.length;
for (var i = 0; i < len; i++) {
if (!temp[this[i]]) {
temp[this[i]] = 'agoni';
arr.push(this[i]);
}
}
return arr;
}
类数组
类数组有要求:
- 属性要为索引(数组)属性
- 必须有 length 属性