js基本知识
一. 特点:
- 解释型语言
- 基于原型的面向对象语言
二. 注释
/* 多行注释, 注释内容不会被执行,但是可以在源码中查看 */ //单行注释
三.书写规则:
- .必须区分大小写
- 每一条语句以分号结尾,
- 如果不以分好结尾,浏览器会自动添加,但是会消耗一部分资源,而且浏览器加分号 可能会出错,所以在开发中,分号必须写
3 .js 会忽略多个空格和换行,所以我们可以利用空格和换行对代码格式化
四. 字面量与变量. 标识符
- 字面量,都是一些不可改变的值,如1, 2, 3,
字面量都是可以直接使用的,都是我们一般都不会直接使用字面量
2. 变量,变量是可以用来保存数据的,而且变量的值是可以任意改变的,方便我们使用
所以我们开发中都是通过变量来保存一个字面量,而很少使用字面量
声明变量要尽量见名思意
a. 声明变量 : var name (没有赋值,此时是undefined)
为变量赋值 name = 'String类型'
b. 声明与赋值同时进行: var name = 'String类型'
3. 标识符, 在js所有可以由我们自己命名的都可以称为标识符 ,例如变量名, 函数名, 属性名
命名规则
1. 标识符可以含有字母,数字 , _ , $
2. 标识符不能以数字开头
3. 标识符不能是ES中的关键字或保留字
4. 标识符一般是采用驼峰命名法
- 首字母小写, 每个单词的首字母大写,其他小写 如 itemName


四. 数据类型
在js中一共有六种基本数据类型
- 基本数据类型(5种)
- String 字符串
- 在js中以引号引起来,单引号' ' , 双引号" " 都可以,但是不可以混着使用
- 同类型的引号不能嵌套, 就是单引号里面不能用单引号, 双引号里面不能使用双引号
- 如果你一定要嵌套, 可以使用\ 来转义 如\"表示" ,\'表示'
- Number 数值
- 在JS中,所有的数值都是Number 类型
- 包括证书和浮点数(小数).
- Number最大值, Number.MAX_VALUE
- 如果表示的数据大于最大值 会返回 Infinity 表示正无穷
- NaN是一个特殊数的数值, not a number
- NaN 使用typeof检查, 也会返回number
- Number的最小值, Number.MIN_VALUE 5e-324
- 计算:
- 在JS中整数运算基本可以保证精确
- 计算浮点数,可能会得到一个不精确的结果
- Boolean 布尔值
- 布尔值只有两个值,true, false, 用来做逻辑判断
- true 逻辑真
- false 逻辑假
- Null 空值
- Null 类型的数值只有一个null
- null这个值专门用来表示一个为空的对象
- 使用typeof检查一个null值时,会返回 object
- Undefined 未定义
- 值只有一个,就undefined
- 当一个变量声明时没有赋值时,他的值就是undefined
- 使用typeof检查undefined时,会返回undefined
-
- s
-
2. 引用数据类型
- Object 对象
- 可以使用运算符 typeof来检查变量的数据类型
3. 类型转换
- 强制类型转换:
- 指将一个数据类型强制类型转换伪其他的数据类型
- 类型转换主要指, 将其他数据类型转换为: String, Number, Boolean
- 将其他数据类型转换伪String
- 方式一: 调用转换数据类型的toString()方法 a.toString()
- 该方法不会把原变量改变,它会将转换结果返回
-
-
但是注意, null和undefined这两个值没有toString方法,如果调用这个方法,会报错
- 方法二: 使用String(a),并将被转换的数据作为参数传递会给函数 String(a)
-
- 对于Number和Boolean, 实际上就是调用toString()方法
- 但是,对于null和undefined ,就不会调用 ,它会将null直接转换伪""null"",undefined 为undefined""
-
-
将其他数据类型转换伪Number
-
方式一:
- 使用Number()函数
- 字符串--->数字
- 如果是纯数字字符串,则直接转换为数字
- 如果字符串中有非数字的内容,则转换伪NaN
- 如果字符串是空格或者是一个全是空格的字符串,则转换为0
- 布尔值转为数字
- true-->1
- false--> 0
- Null 转化为数字
- 0
- Undefined转化为数字
- NaN
- 字符串--->数字
- 使用Number()函数
- 方式二
- 使用parseInt() ,把字符串转化为整数,
- 可以把字符串中有效的整数内容(字符串前面的整数)提出来了
- 如果非要使用parseInt(), parseFloat(),它会先将其转换为String,然后再操作
- 使用parseFloat(), 把字符串转化为浮点数
-
- 方式一: 调用转换数据类型的toString()方法 a.toString()
- 将其他数据类型转换伪String
-
- 其他进制
- 16进制 以0x开头
- 8进制,以0开头
- 二进制,以0b开头,但是不是所有浏览器都支持二进制
- 问题:在浏览器中,像"070"这种字符串,有些浏览器会当成8进制解析,有的会当成10进制解析
- j解决: 可以在parseInt()中传递第二个参数,来指定数字的进制 a = parseInt(a. 10)
-
-
- 将其他类型转为Boolean() -->Boolean(a)
- 调用Boolean()函数来转换
- 0, NaN, " ", Null,Undefined,都是false
- 其他都是 true, 包括对象
- 将其他类型转为Boolean() -->Boolean(a)
-
五, 运算符
运算符也叫操作符,通过运算符可以对一个或多个值进行预算,并获取运算结果
- 算数运算符 (不会改变原值),
- 当对非Number值进行运算时(除字符串类型),会先转为数字,
- 任何值和NaN运算,都是NaN
- + 加法
- 字符串相加,会进行拼串
- 任何值和字符串相加,都会拼串, 转换为字符串
- 可以使用 c = c + "" 来转换为字符串(隐式转换)
- - 减法
- / 除法
- * 乘法
- 任何值和数字相 - / *,结果都是Number类型
- 可以使用 d = d*1 来把其他类型数据转换为Number ,(隐式转换)
- % 取模运算,, 取余数
-
-
- 一元运算符
- 只需要一个操作数
- + 正号 可以使用+号将任何数值转换为Number类型
-
result2 = +'3' + 2 + 1console.log(result2)//6
-
- - 负号
- 自增
- a++ 和++a
- a++ 先赋值再自增
- ++a 先自增再赋值
-
-
-
自减
-
a-- 和 --a
- a-- 先赋值再自减
- --a 先自减再赋值
-
- 逻辑运算符
- && 与
- 所有为true才返回true
- 只要有一个值是false ,就返回false
- 短路与,只要遇到第一个为false,就不会往后看
- || 或
- 只要有一个为true.则为true
- JS中的||是短路或, 只要遇到第一个为true的值,就不会往后检查
- ! 非(取反)
- Boolean值取反
- 对非Boolean取反,先变成Boolean,再取反
- 可以对非Boolean两次取反, 转换为Boolean值(隐式转换)
- 非Boolean的逻辑运算
- 先对其转换为Boolean值,再运算赋值给(但是,不会对自己的原值有影响)
- &&
- 两个true,返回后面那个值
- 前面false,返回false那个值
- ||
- 前面那个true,返回前面的
- 两个值||, 前面的是false,直接返回后面的
- && 与
- 赋值运算符
- a += 1 ==> a = a+1
- 关系运算符
- 关系成立返回true,关系不成立返回false
- > 大于, < 小于 ,>= 大于或等于, <= 小于或等于
- 任何值与NaN作比较都是false
-
两个字符串比较,比较的是它们的字符串编码
-
- 相等运算符 ==
- 当使用==来比较两个值时,类型不同,会将其转换为相同类型
- undefined衍生至null,所以,两个值做比较时,会返回true
- NaN不和任何值相等,包括它本身
- 可以通过isNaN()函数来判断一个值是否是NaN
-
6. 不相等!=
7. 全等 === 不会做类型转换, 会比较他们的类型
8. 不全等!== 不会做类型转换, 类型不同就false
8.条件运算符
- 页叫三元运算符 条件表达式? 语句1:语句2
- t条件表达式为rue时, 执行语句1
- 条件表达式为false时,执行语句.
-
9.运算符的优先级
-
&& > ||
-
可以用( ) 来改变优先级
-
-
六.代码块
我们程序是有一条一条语句执行的,,一般是自上向下顺序执行的
- 一个{ } 中的语句我们也称为一个代码块
- 在代码块后边就不用再编写; 了
- 代码块只有分组作用,没有其他作用
- 语句分类:
- 条件判断语句
- 使用条件判断语句可以在执行某个语句之前进行判断,如果成立才立刻执行,条件不成立不执行
- 语法
-
-
-
1.if(条件表达式){
执行语句一; }
2. if(条件表达式){ 执行语句一; }else { 执行语句二; }
3.if(条件表达式){执行语句一; }else if{ 执行语句二; }else{
执行语句三
}
-
-
-
- 语法
- 使用条件判断语句可以在执行某个语句之前进行判断,如果成立才立刻执行,条件不成立不执行
- 条件分支语句
- 如果没有break,会从表达式匹配的地方,往后的语句都执行,所以case要带一个break,以保证不会执行其他语句
-
-
-
-
-
switch(条件表达式) { case 表达式1: 语句一; break; case 表达式2: 语句二; break; default: 语句三; break; }
-
-
-
-
- 循环语句
- 如果判断表达式为true,语句一直执行,直到为false
-
-
-
-
while循环:先判断后循环 while(判断表达式) { 语句... } do-while: 先循环一次再判断 do { 执行语句... }while(判断表达式) for循环: for(1.初始表达式; 2.条件表达式; 3.更新表达式){ 执行语句... }
-
-
-
-
- 如果判断表达式为true,语句一直执行,直到为false
- 条件判断语句
运用 题目:
/** * 打印一个三位数的百十个位数字的3次方相加为其自身 */ for(var i = 100; i < 1000; i ++){ //获取i的百位,十位,各位的数字 var b = parseInt(i/100); var t = parseInt(i/10 - b*10); var g = i%10; //乘方;Math.pow(数值, 乘方) // if((b*b*b + t*t*t +g*g*g) == i){ if((Math.pow(b, 3) + Math.pow(t, 3) +Math.pow(g, 3)) == i){ console.log(i)//153,370,371,407 } }
七.对象
对象是一个复合的数据类型,在对象中科院保存多个不同数据类型的属性
- 内建对象
- 在ES标准定义中,在任何的ES的实现中都可以使用
- 比如, Math,String, Number,Booean, Function,Object....
- 宿主对象
- 由JS的运行环境提供的对象,目前来讲只要你指由浏览器提供的对象
- 比如BOM, DOM
- 自定义对象
- 由开发人员自己创建的对象
- 创建对象
- 使用new关键字调用的函数, ,是构造函数constructor
- new对像的过程
var Person = function(name, age) { this.name = name; this.age = age; }; var p = new Person("bella", 10); console.log(Person.prototype); console.log(p);
对比一下,发现p的__proto__的值就是构造函数Person的prototype的属性值。
因此new操作符创建对象可以分为以下四个步骤:
1. 创建一个空对象 2. (设置原型链)将所创建对象的__proto__属性值设为构造函数的prototype的属性值 3. 构造函数中的this指向该对象,执行构造函数中的代码
4. 返回对象
- new对像的过程
-
添加属性
- 语法 对象.属性名 = 属性值
- 读取属性
- 语法: 对象.属性名, 如果属性不存在, 返回undefined
- 修改对象属性
- 语法 对象.属性名= 新属性值
- 删除属性
- 语法 delete 对象.属性名
- 使用new关键字调用的函数, ,是构造函数constructor
- 对象的属性名不强制要求遵守标识符的规范,但是我们使用的还是尽量按照标识符的规范取做
- 如果要使用特殊的属性名,不能采用.的方式来操作, 可以使用另一种方式, 读取时也是要按照这种方式
- 语法: 对象["属性名"] = 属性值
- 使用[ ] 这种形式去操作属性,更加灵活,
- 在[ ]中可以直接传递一个变量, 这样变量值是多少,就会读取那个属性
- 1
- 如果要使用特殊的属性名,不能采用.的方式来操作, 可以使用另一种方式, 读取时也是要按照这种方式
- 属性值,JS的属性值 可以是任意的值
- in 运算符, 检查对象中是否含有这个属性 ,如果有,返回true,否则false,,
- "属性名" in obj
- JS中的变量都是保存在栈内存里的
- 基本数据类型的值都是直接存储在栈内存中的
- 值与值之间是独立存在的,修改一个变量不会影响其他的变量
- 对象是保存在堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间
- 而变量保存的是对象的内存地址(对象的引用), 如果两个变量保存的是同一个对象引用,如果其中一个变量修改属性值,则另一个变量的相应属性值也会改变
- 而变量保存的是对象的内存地址(对象的引用), 如果两个变量保存的是同一个对象引用,如果其中一个变量修改属性值,则另一个变量的相应属性值也会改变
- 基本数据类型的值都是直接存储在栈内存中的
-
当比较基本数据类型时,是比较它们的值,而比较引用数据类型的时候,是比较它们的对象的内存地址
-
如果两个对象是一模一样的,都是地址不同,它还是会返回false
-
- 对象字面量:
- 使用对象字面量来创建对象 var obj = { }
- 创建对象字面量,可以在创建对象时,直接指定对象中的属
- 语法: {属性名:属性值, 属性名:属性值}
- 对象字面量的属性名可以加引号,也可以不加, 但是如果要使用一些特殊的属性名,则必须加引号
八. 函数
函数Function()也是一个对象,函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)
- 使用typeof检查时,会返回function
- 封装到函数中的代码不会立即执行,会在调用时才执行
- 使用函数声明创建一个函数
- 语法:
//实际上在开发过程中不会使用构造函数 // var fun = new Function("console.log('Hello')"); // fun(); //一般声明函数 function 函数名(形参1,形参2) { 功能代码
return 返回值 } //调用 函数名(); //使用函数表达式来创建一个函数 var 函数名 = function(形参1,形参2) { 功能代码 };//匿名函数,只能调用一次(function(){console.log("匿名函数")})()
- 语法:
- 函数的形参实参
- 在函数() 内可以指定一个或多个形参(形式参数)
- 在函数调用时,可以在() 内指定实参(实际参数)
- 调用函数时解析器不会检查实参的类型,所以要注意是否会接收到非法参数,如果有可能则需要对形参进行类型检查
- 如果实参的数量少于形参的数量,则对应的实参将是undefined
- 如果实参的数量多于形参的数量,则会省略后面的
- return 返回值
- continue,break,return
- continue: 退出本次循环
- break;退出循环
- return 结束函数 ,返回值
- 2
- d
- 方法
- 函数也可以称为对象的属性,如果一个函数作为对象的属性保存,那么我们称这个函数为这个对象的方法,调用这个函数就说调用对象的方法(method), 但是它们只是名称上的区别
- 枚举对象的属性 使用for...in 语句
- 语法 for(var 变量 in 对象)
- for... in 语句对象有几个属性,就循环体就会执行几次,每次执行时,就会将对象非因公属性的名字赋值给变量
- 作用域: 值一个变量的作用的范围 (JS因公有六种作用域)
- 全局作用域
- 直接表写在script标签的JS代码,都在全局作用域
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在去全局作用域中,有一个全局对象window
- 它代表的是一个浏览器的窗口,它是由浏览器创建,我们可以直接使用的
- 在全局作用域中,
- 创建的变量都会作为window对象的属性保存
- 创建的函数都会作为window对象的方法保存
- 创建的变量都会作为window对象的属性保存
- var的变量提升
- 变量的声明提前
- 使用var关键字声明的变量,会在所有的代码执行前被声明(但是不会被赋值,值还在原地)
- 但是如果声明变量时不使用var关键字,则变量不会被声明提前
- 函数的声明提升
- 使用函数声明形式 function 函数名() { },它会在所有代码执行前就被创建,所以我们可以在函数声明前来调用函数
- 使用函数表达式创建的函数,不会被提前,所以不能在声明前调用
-
function run() { console.log("我要跑步")//我要跑步 } var fn = function() { console.log("fn")//fn } run(); fn()
区别:run();fn()//函数声明会提前function run() {console.log("我要跑步")//我要跑步}//函数表达式不会提前var fn = function() {console.log("fn")//出错}
-
- 函数作用域(局部作用域)
- 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
- 没调用一次函数就会创建一个新的函数作用域,它们之间是互相独立的
- 在函数中可以访问全局作用域,在全局作用域不能访问函数作用域
- 当函数作用域操作某个变量时,会优先在自己的作用域中查找,没有,再去上一级查找
- 在函数作用域中也有声明提前
-
var a =10 function fn() { console.log(a);//undefined var a = 11;// var 声明提前 } fn() function fn2() { console.log(a)//10 a = 11; } fn2()
-
- 全局作用域
- debug(打断点)
- this
- this指向函数的调用者
- 解析器在调用函数每次都会向函数内部传递一个隐含的参数,这个隐含的参数就是this,this指向的是一个对象
- 这个对象我们成为函数的上下午执行者
- 根据函数的调用方式不同,this指向不同的对象
- 以函数形式调用,this永远是window
- 以方法的形式调用,this就是调用方法的对象
九.构造函数
-
创建一个构造函数
-
构造函数就是一个普通函数,创建方式和普通函数没有区别
- 但是,调用的方式不同,普通函数时直接执行,构造函数需要new关键字来调用
-
- 构造函数执行的流程
- 立刻创建一个新对象
- 将新建的对象设置为构造函数中this,
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
-
function Persion (name, age){ this.name = name; this.age = age;2 this.sayName = function() { console.log(this.name) }; } var p = new Persion("XIAO", 20,); p.sayName() console.log(p)
-
- 实例
- 通过构造函数创建的对象是实例
- 通过instanceof可以检查一个对象是否是实例
- 语法: 对象 instanceof 构造函数
- 如果是,返回true, 否则返回false
- 所有的对象都是Object的实例 ,返回true
-
console.log(p instanceof Persion)//true console.log(p instanceof Object)//true
-
-
-
构造函数的改进
- 问题,上面的函数
- 每创建一个对象,会为sayName方法开创一片地址,多个对象时,占内存多
- 解决:
-
function Persion (name, age){ this.name = name; this.age = age;2 this.sayName = fun; } //在全局中创建 function fun() { console.log(this.name) }; var p = new Persion("XIAO", 20); var p2 = new Persion("MING", 19); p.sayName()//XIAO p2.sayName()//MING console.log(p.sayName == p2.sayName) //true//指向同一片地址
- 问题,上面的函数
- 原型prototype对象(构造函数再改进)
- 问题: 将sayName方法定义在全局作用域中
- 污染了全局作用域的命名空间
- 而且定义在全局作用域中也不安全
- 我们每一次创建一个函数,解析器都会向函数中添加一个属性Prototype
- 这个属性对应着一个对象,这个对象就是我们所谓的原型对象
- 如果作为普通函数的形式调用,它所创建的对象都会有一个隐含的属性指向该构造函数的原型对象,我们可以通过__proto__来访问该属性
- 原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象
- 我们可以将对象中共有的内容,统一设置到原型对象中
- 当我们访问对象的一个属性或方法的时候,它会先在对象自身中寻找,如果有则直接使用,如果没有则会取原型对象中寻找,如果找到则直接使用
- 以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,这样就不用分别为每个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了
-
-
function Persion (name, age){ this.name = name; this.age = age;2 // this.sayName = fun; } //向原型中添加sayName Persion.prototype.sayName = function(){ console.log(this.name) }
var p = new Persion("XIAO", 20);var p2 = new Persion("MING", 19);p.sayName()//XIAOp2.sayName()//MINGconsole.log(p.sayName == p2.sayName) //true//指向同一片地址
console.log(p instanceof Persion)//trueconsole.log(p instanceof Object)//true
-
- 问题: 将sayName方法定义在全局作用域中
- 检查对象含有某个属性值
- 使用in检查 "属性名" in 对象
- 如果对象中没有,但是原型中有,也会返回true
- 使用对象的hasOwnProperty() 来检查对象自身是否含有该属性
- 使用该方法,只有当对象自身中含有该属性时,才会返回true
- 使用in检查 "属性名" in 对象
console.log("sayName" in p)//true console.log(p.hasOwnProperty("sayName"))//false
垃圾回收(GC):
- 当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,所以垃圾必须回收
- 我们需要垃圾回收机制,来处理程序中的垃圾
- 在JS中拥有自动的垃圾回收机制,会将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作
- 我们需要做的只是将不再需要使用的对象设置为null
十.数组(Array)
- 数组也是一个对象,也是用来存储一些值的
- 不同的是普通对象是使用字符串作为属性名的, 而数组是使用数字来作为索引操作对象
- 索引:从0开始
-
创建数组
- var arr = new Array()
- 使用数组字面量
- var arr = [1,2,3,4]
- 使用构造函数创建数组(不常用)
- var arr =new Array(1,2,3,4)
- 查看数组长度
- 所以尽量不要创建非连续数组
//1. 创建数组 var arr = new Array() //2. 添加元素 arr[0] = 1; arr[10] = 10 console.log(arr)// [1, empty × 9, 10] //3. 查看数组长度,这个会获取到这个数组最大的索引+1 console.log(arr.length)//11
//改变数组长度,长度大于原数组时,会把多出来的部分赋空,//长度小于原数组,会把多出的元素删除arr.length = 12console.log(arr)//(12) [1, empty × 9, 10, empty]arr.length = 2console.log(arr)//[1, empty]//在数组最后面添加一个元素 arr[arr.length] = 10
- 所以尽量不要创建非连续数组
-
数组操作方法
- push() 在数组末尾添加一个或多个元素, 并返回新的数组
- pop() 删除数组最后一个元素,并将删除的元素返回
- unshift() 在数组开头添加一个或多个元素,返回新数组
- shift() 删除数组的第一个元素,并将删除的元素作为返回值返回
- 数组的遍历
- for循环
for(var i = 0; i < arr.length; i++) { console.log(arr[i]) }
-
forEach()
- 这个方法只支持IE8以上的浏览器
- forEach()需要一个函数作为参数
- 数组中有几个元素,函数就会执行几次,每次调用时,浏览器将会遍历数组,以实参形式传递进来
-
-
-
- 1
-
-
- for循环
- slice()和splice()
- slice(startIndex, endIndex) 可以用来从数组中提取指定的元素,返回到新数组中
- startIndex截取位置开始索引,包含索引
- endIndex截取结束的索引,不包含这个索引
- 可以传负值,从后往前计数
- splice(startIndex,count,newValue) 可以用来删除/替换/插入数组中的元素
- startIndex删除开始的索引, count删除的元素个数
- newValue 可以传递一些新元素,这些元素将会自动插入到开始位置索引前面
- 使用splice会影响到原数组,会将指定删除的元素作为返回值
-
//删除数组中重复的元素 for(var i = 0; i < arr.length; i++){ for(var j = i + 1; i < arr.length; j++) { if(arr[i] == arr[j]){ arr.splice(j,1); // 问题:相邻位置有相同的元素,会遗落掉 // 因为当删除当前j的元素后,后边的元素会自动补位,此时,将不会比较这个元素, // 我们需要在比较一次就所在位置的元素 j--; } } } console.log(arr)
- slice(startIndex, endIndex) 可以用来从数组中提取指定的元素,返回到新数组中
- concat() 可以连接两个或者多个数组,并将新的数组返回, 该函数不会对原数组有影响
- jion() 可以将数组转换为一个字符串,不会影响原数组, 而是将转化后的字符串作为结果返回
- 可以传一个字符串,这个字符串将作为连接符,默认逗号,
- reverse() 反转数组 ,会影响原数组
- sort() 可以用来对数组排序,会影响原数组
- 按照Unicode编码排序,即使是纯数字也是
- 可以添加一个回调函数,来指定排序规则
- 需要定义两个形参,
-
-
var arr1 = ['w', 's', 'z'] var arr2 = ['p', 'l', 'z', 's'] var arr3 = arr1.concat(arr2) console.log(arr3)//["w", "s", "z", "p", "l", "z", "s"] var str = arr1.join(); console.log(str)//w,s,z arr1.reverse() console.log(arr1)//["z", "s", "w"] arr1.sort() console.log(arr1)//["s", "w", "z"] var arr4 = [1,2,4,5,211,13,77] arr4.sort() console.log(arr4)//[1, 13, 2, 211, 4, 5, 77] 按照Unicode编码 //1 交换; 0 相等,位置不变; -1 符合要求位置不变 arr4.sort(function(a,b){ if(a > b ) { return 1;//交换,这是从小到大排序,如果要从大到小,可以设置返回-1 }else if (a < b){ return -1; }else{ return 0 } }) console.log(arr4)//[1, 2, 4, 5, 13, 77, 211]
-
call() 和apply() 这两个都是函数对象的方法,需要通过函数对象来调用
- 在调用call和apply()可以将一个对象指定为第一个参数,此时这个对象就会成为函数执行时的this
- 即改变this指向
- call()方法可以将实参在对象后面依次传递
- apply()方法需要将实参封装到一个数组中统一传递
-
-
arguments 实参
在调用函数时,浏览器每次都会传递两个隐含的参数
- 函数的上下文对象this
- 封装实参的对象 arguments
- arguments 是一个类数组对象,它可以通过索引来操作数据,也可以获取长度
- 在调用的时候,我们传递的实参都会在arguments中保存
- arguments.length 可以用来获取实参的长度
- 即使我们没有定义形参,也可以通过arguments来使用实参
- 有属性callee,指向真正执行的函数对象
Date 对象
在js中使用date来表示一个时间
- 直接使用构造函数创建一个Date对象,则会封装为当前的代码执行时间
- 创建一个指定的时间,需要在构造函数中传递一个表示时间的字符串作为参数
- 日期格式为: 月份/日/年' 时:分:秒
- 方法:
- getDate() 获取当前日期对象是几日
- getDay() 获取当前日期对象是周几, 返回0~6的值, 0表示周日
-
<script> var d = new Date() var d1 = new Date("9/10/2020 8:20:00") //getDate()获取时间对象的日 var date = d1.getDate() //getDay()获取时间对象是周几 var day = d1.getDay() //getMonth()获取时间对象的月份,0~11, 0表示1月, 11 表示12月 var month = d1.getMonth() //getFullYear()获取时间对象的年份 var year = d1.getFullYear() //getTime()获取当前时间戳,指格林威治时间的1970年1月1日 0时0分0秒到时间对象的毫秒数,1s = 1000ms var time = d1.getTime() //获取时间戳来测试代码的执行的性能 var startTime = Date.now() // {需要测试的代码} var endTime = Date.now() var dutime = endTime -startTime console.log(d)//Mon Sep 14 2020 20:37:30 GMT+0800 (中国标准时间) console.log(d1)//Thu Sep 10 2020 08:20:00 GMT+0800 (中国标准时间) console.log(date)//10 console.log(day)//4 console.log(month)//8 console.log(year)//2020 console.log(time)//1599697200000 </script>
Math 是一个工具类
是一个工具类,不用创建对象,里面封装了数学运算相关的属性与方法
<script> // abs()可以用来计算一个数的绝对值 console.log(Math.abs(-2))//2 //ceil() 对一个数进行向上取整,小数位只要有值就自动进1 console.log(Math.ceil(2.1))//3 //floor() 对一个数进行向下取整,小数位只要有值就自动舍弃 console.log(Math.floor(2.1))//2 //round() 对一个数进行四舍五入 console.log(Math.round(2.1))//2 // random() 可以用来生成一个0 - 1 之间的随机数 console.log(Math.random())//0.8071396863608609 // Math.round(Math.random()*10) 生成一个0-10 之间的随机整数 console.log(Math.round(Math.random()*10) )//1 // 生成一个x-y之间的随机数 // Math.round(Math.random()*(y-x) + x) // 生成一个1-10之间的随机数 console.log(Math.round(Math.random()*9) + 1 )//9 //max() 可以获取多个数中的最大值 console.log(Math.max(2.1, 88,0))//88 //min()可以获取多个数中的最小值 console.log(Math.min(2.1, 88,0))//0 //pow(x,y)返回x的y次幂 console.log(Math.pow(2, 3))//8 // sqrt() 用于对一个数进行开方 console.log(Math.sqrt(9))//3 </script>
包装类 object
在JS中,提供了3个包装类,通过3个包装类可以将基本数据类型的数据转换为对象
但是,在实际开发中,一般不用基本数据类型的对象