JavaScript 学习笔记(二)-- ECMAScript

news/2024/12/4 17:25:24/

ECMAScript

客户端脚本语言的标准

基本语法

与html结合方式

  1. 内部JS:

    • 标签体内容就是js代码

      <script text="text/javascript">// 内容
      </script>
      
  2. 外部JS:

    • 通过src属性引入外部的js文件

      <script text="text/javascript" src="location">// 内容
      </script>
      

注意:

  1. 可以定义在html页面的任何地方。但是定义的位置会影响执行顺序;
  2. 可以定义多个;
  3. 同一个标签不能同时引入外部 同时有内部的,这样的话只有外部的好使。

注释

  1. 单行注释://注释内容
  2. 多行注释:/注释内容/

数据类型

原始数据类型(基本数据类型)
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

  1. null:一个对象为空的占位符
  2. undefined:未定义。如果一个变量没有给初始化值,则会被默认赋值为undefined

存放在 里,规则 先进后出

引用数据类型
  1. Array:数组。

  2. Object:对象。

  3. function:函数。

存放在 里,拷贝的是地址

变量

概念

一小块存储数据的内存空间

强弱类型

Java语言是强类型语言,而JavaScript是弱类型语言。

  • 强类型:在开辟变量存储空间时,定义了空间将来存储的数据的数据类型。只能存储固定类型的数据
  • 弱类型:在开辟变量存储空间时,不定义空间将来的存储数据类型,可以存放任意类型的数据。
全局&局部变量

访问规则

  • 里面的可以访问到外面的,外面的不能访问里面的
定义语法
var 变量名 = 初始化值;// 定义多个遍历并赋值
var a = 10,b = 20,c = 30,d = 40,e;
document.write(a,b,c,d,e);
命名规则
  1. 变量名必须以英文字母、_ 、$ 开头;
  2. 变量名可以包括英文字母、_ 、$ 、数字;
  3. 不可以用系统的关键字、保留字作为变量名。
typeof 操作符

获取变量的类型。

number string boolean object undefined function

console.log(typeof(123)); // number
console.log(typeof("123")); // string
console.log(typeof(true)); // boolean

用法:

  • typeof(值)
  • typeof 值

注:

  1. null、array 运算后得到的是object

  2. 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. 1/0 会得 Infinity(无穷)
  2. 1/0 会得 -Infinity
  3. 0/0 会得 NaN
赋值运算符

​ = += -= *= /= %=

比较运算符

​ < >= <= == ===(全等于)

比较方式:

  1. 类型相同:直接比较

    ​ 字符串:按照字典顺序比较。按位逐一比较,直到得出大小为止。即 ASCII码 值

  2. 类型不同:先进行类型转换,再比较

    ​ ===:全等于。在比较之前,先判断类型,如果类型不一样,则直接返回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
括号运算符
  1. 优先运算

    将里面的内容变为表达式

    (function () {}) 函数声明失效,变为表达式

  2. 立即执行

    (function () {})()

流程控制语句

  1. if…else…

    if(判断语句) {条件体
    }
    
  2. 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;
    }
    
  1. while

    底层机制就是 for 循环:for 循环括号内两边不写语句就是 while 循环:for (;条件语句;) {}

    while(条件语句) {循环语句
    }
    
  2. do…while

    先执行一次,再判断条件语句

    do {循环体
    } while (条件语句)
    
  3. for

  4. break

    跳出循环或者 switch

  5. continue

    终止本次循环进行下次循环

JS特殊语法

  1. 语句以 ; 结尾,如果一行只有一条语句则 ; 可以省略 (不建议)
  2. 变量的定义使用 var 关键字,也可以不使用
  • 用:定义的变量是局部变量
  • 不用:定义的变量是全局变量(不建议)
  1. 练习: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) +"&nbsp;&nbsp;&nbsp;");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 一块出现做区分

特点
  1. 方法定义时,形参的类型不用写,返回值类型也不写
  2. 方法时一个对象,如果定义名称相同的方法,会覆盖
  3. 在JS中,方法的调用只与方法的名称有关,和参数列表无关
  4. 在方法声明中有一个隐藏的内置对象(数组),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]);
}
继承 --> 圣杯模式
  1. 传统形式 --> 原型链

    • 过多的继承了没用的属性
  2. 借用构造函数 call()/apply()

    • 不能继承借用构造函数的原型
    • 每次构造函数都要多走一个函数(视觉上减少代码,但多走了方法)
  3. 共享原型

    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"
    
  4. 圣杯模式 *

    // 通俗写法
    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:数组对象

创建
  1. var arr = []; 数组字面量 – 推荐使用

    var arr = [1,2,3];var arr = [,,]; // [undefined * 2]
    var arr = [1,,2]; // [1, undefined, 2] --> 稀松数组
    
  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 留了一个接口让用户自定义排序方式

规则:

  1. 必须写俩形参
  2. 看返回值
    1. 当返回值为负数时,那么前面的数放在前面
    2. 为正数,那么后面的数在前
    3. 为 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;
}
类数组

类数组有要求:

  1. 属性要为索引(数组)属性
  2. 必须有 length 属性

http://www.ppmy.cn/news/341828.html

相关文章

2021-07-21淘宝网第二次尝试

<div id"headmessage" class"leayer clearfix"><ul class"fl"><a href"https://www.taobao.com"><li>中国大陆</li></a><span class"iconfont">▼</span><a href"…

智能穿戴及传感器调研:第二阶段

可穿戴传感器底层原理 摘要&#xff1a;传感器原理按过程基本分四层&#xff1a;现实层&#xff0c;电信号转换层&#xff0c;集成电路层&#xff0c;信号处理层。现实层将现实信息转换为传感器将要测量的量&#xff1b;电信号转换层是将测量量转换为电学信号&#xff1b;集成…

C++实验八——类的继承(2)

实验报告 题目1题目2 【实验名称】 实验八 类的继承&#xff08;2&#xff09; 【实验内容】 题目1 正确使用类的继承和组合进行类的设计&#xff0c;分别表示房间、休息室、教室、投影仪&#xff0c;沙发&#xff0c;为每个类设置适当的成员变量、成员函数和构造函数&#x…

特斯拉Model S 引爆电动车市狂鸣

电动汽车发展的缓慢进程消耗了我们对它的信心和激情&#xff0c;直到静谧的Tesla特斯拉电动轿跑出现&#xff0c;让兴趣缺缺的我们重新提起了精神。更让人振奋的是&#xff0c;我们有幸接触到了这款车型中动力最为强劲的高性能版本——Signature Performance版&#xff0c;下面…

python将列表中的偶数变成平方、奇数不变_编写程序,将列表s=[9,7,8,3,2,1,5,6]中的偶数变成它的平方,奇数保持不变,运行效果如书上图所示。_学小易找答案...

【简答题】第2题编写代码 【简答题】提交40倍物镜下的皮肤全层切片照片,并至少标注表皮层,真皮层,皮下组织。 【简答题】编写程序,计算Sn=1-3+5-7+9-11.... 【判断题】DHCP是局域网的一个网络协议,使用TCP协议工作。答案: 【简答题】编写程序,将列表s=[9,7,8,3,2,1,5,6]中的偶数…

Python编程题(二)

demo19&#xff1a; 1.你可以通过询问5个问题来找出你朋友的生日在-一个月中的哪天。每个问题都在询问这一天是否在5个数字集中。 生日就是出现这个数字的集合的第- L 个数字的和&#xff0c;例如:如果生日是19&#xff0c;那它就会在setl. set2和set5中出现。这三个集合的第…

[解读] GuiltyGearXrd‘s Art Style : The X Factor Between 2D and 3D - GGX 3D 渲染 2D 风格

文章目录 目的注意What Ill Cover todayQuick introductionMy history with the industry - 本村的自我介绍The Art Style of GuiltyGear Xrd - GGX 的美术风格What we achieved with it - 我们实现了什么&#xff1f; Why this Style?So Why Cel-shaded 3D? - 那么&#xff…

LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置

给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。 示例 1&#xff1a…