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:
-
浮点数精度不准
console.log(0.14 * 100); // 14.000000000000002
-
小数点前 以及 小数点后 位数大于 16 会出现精度问题
console.log(1000000000000001 + 1000000000000001) // 2000000000000002 console.log(10000000000000001 + 10000000000000001) // 20000000000000000console.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() 返回的值是字符串类型
console.log(typeof(typeof(a))); // string
特殊:
变量不定义就使用必定会报错,只有一种情况下不会
console.log(typeof(a)); // undefined
自定义 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
[] - 1; // -1
&& || !
判断调用 Boolean() 方法
< > …
(比较符号)
var a = 3 > "2"; // boolean: true
var a = "3" > "2"; // 会比较对应的 ASCII码 值
特殊
undefined > 0; // false 不转换,系统规定 undefined 和 null 不能和数进行比较
null > 0; // false
== !=
调用 Boolean() 方法
var a = 1 == true; // boolean: true
引用值比较的是地址:
{} == {}; // false
[] == []; // falsevar 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
后面的第二个参数表示此数所表示的进制
parseInt("B", 16); // 11
后面填 0
- 有的浏览器是 原样转换整型输出
- 有的是输出 NaN
parseFloat()
注:看到除了第一个 . 的非数字位截止
parseFloat("123.12abc"); // 123.12
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
特殊:
NaN === NaN; // 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'
// 先读小括号内的,即先赋值
三元运算符
语法:
表达式 ? 值1 : 值2;
判断表达式的值,如果是 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 = 1document.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:数字对象
var num = new Number(123);
String:字符串对象
var str = new Stirng('abcd');
Boolean:布尔对象
var bol = new Boolean('true');
详解
原始数据类型不能有自己的属性和方法
自定义属性
但下面这个却不报错:
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 = 0for (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]); // 2arguments[0] = 3;console.log(a); // 3b = 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"
对象中固定不变的属性(公有的内容)可以提取出来放到原型中,避免代码多次执行造成冗余。
增删改查
删
delete Person.prototype.LastName;
经过了 var 给 window 上增加的属性为不可配置性属性,delete无法删除。
增改查
Person.prototype.LastName = "Agoni";
设置属性(可以多个一起设置)
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()
test(); // --> test.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(1,2,3,4,5);
和 数组字面量 区别:
// 只传一个参数,代表数组的长度 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 属性