new操作符的作用?
- 创建一个新对象
- 构造函数的this指向新对象
- 逐次执行构造函数中所有代码
- 返回新对象
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function () {
alert('hello')
}
}
var per = new Person('aa', 18)
console.log(per)
// instanceof 检查一个对象是否是类的实例
console.log(per instanceof Person) //true
// 所有对象都是object的后代,任何对象和Object instanceof都返回true
console.log(per instanceof Object) //true
this的情况
- 当以函数的形式调用时this是window
- 当以方法的形式调用时,this是调用方法的对象
- 当以构造函数调用时,this是新创建的那个对象
- 使用call和apply调用时,this是指定的那个对象
原型对象
function MyClass() {
}
MyClass.prototype.a = 1;
MyClass.prototype.sayhello = function () {
console.log('aaaaaa')
}
var par = new MyClass()
console.log(par.a)
console.log('a' in par)
//in 检查对象中是否有某个属性,对象自身中没有原型中有也为true
var par1 = new MyClass()
par1.sayhello()
console.log(par1.hasOwnProperty('sayhello')) //false
//hasOwnProperty()检查自身是否有某个属性,自身中含有才为true
console.log(par1.hasOwnProperty('hasOwnProperty')) //false
console.log(par1.__proto__.hasOwnProperty('hasOwnProperty')) //false
console.log(par1.__proto__.__proto__.hasOwnProperty('hasOwnProperty')) //true
console.log(par1.__proto__.__proto__.__proto__) //null
console.log(par1.b) //undefined
- 原型的对象也是对象,所以他也有原型,当我们使用一个对象的属性或方法时首先会在自身寻找,自身中如果有则直接使用,自身中没有就到原型对象中找,原型对象中有则直接使用,没有就到原型的原型中找,直到找到Object中的原型,Object原型没有原型,如果在Object原型依然没有找到则返回undefined
垃圾回收(GC)
- 当一个对象没有任何变量或属性对他进行引用,此时我们将永远无法操作改对象,此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行空间变慢,所以这种垃圾必须进行清理。
- 在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收操作,我们需要做的只是将不再使用的对象设置null即可
call()和apply()
- 两个方法都是函数对象的方法,需要通过函数对象来调用,当函数调用call()和apply()都会调用函数执行
- 在调用call()和apply()可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的this
- call()方法可以将实参在对象之后依次传递
- apply()方法需要将实参封装到一个数组中统一传递
function fun(a, b) {
console.log(this)
console.log('a=' + a)
console.log('b=' + b)
}
var obj = {}
fun(2, 3) //this是window
fun.call(obj, 2, 3) //this是obj
fun.apply(obj, [2, 3]) //this是obj
arguments
在调用函数时,浏览器每次都会传递近两个隐含的参数
1.函数的上下文对象this
2.封装实参的对象arguments
- arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度arguments.length
- 在调用函数时,我们所传递的实参都会在arguments中保存
- 不定义形参也可以通过arguments来使用实参, arguments[0]表示第一个实参
- callee属性,就是当前正在指向的函数的对象
function fun() {
console.log(arguments[1]) //aa
console.log(arguments.callee == fun) //true
}
fun(12, 'aa')
数组方法
arr = [11, 4, 2, 8, 3, 4, 7, 5, 6]
arr.sort()
//排序会影响原数组,默认按unicode编码排序
arr.sort(function (a, b) {
return a - b
}) //按升序对数组进行排序
console.log(arr)
// [2, 3, 4, 4, 5, 6, 7, 8, 11]
console.log(arr.reverse())
//反转数组中元素顺序,改变原数组
arr.splice(1, 2, 'a', 'b')
//删除从索引1开始的2个元素,把'a','b'添加至数组索引1的地方
console.log(arr)
// [11, 'a', 'b', 6, 5, 4, 4, 3, 2]
console.log(arr.slice(1, 2))
//['a'] 截取索引1到2的元素,不包括2,不改变原数组
console.log(arr.push(12, 9))
//数组末尾追加元素,返回数组长度,改变原数组
console.log(arr.pop())
//数组末尾删除一个元素,返回删除的元素,改变原数组
三个包装类
- 基本数据类型
String Number Boolean Null undefined Symbol bigInt - 引用数据类型
Object - 在JS中为我们提供了三个包装类,通过这三个包装类可以将基本数据类型的数据转换为对象
- String() 可以将基本数据类型字符串转换为String对象
- Number() 可以将基本数据类型数字转换为Number对象
- Boolean() 可以将基本数据类型布尔值转换为Boolean对象
- 但是注意:我们在实际应用中不会使用基本数据类型的对象,如果使用基本数据类型的对象,再做一些比较时可能会带来一些不可预期的结果
- 方法和属性只能添加给对象,不能添加给基本数据类型
- 当我们对一些基本数据类型的值去调用属性和方法时,浏览器会临时使用包装类将其转换为对象,然后再调用对象的属性和方法,调用完以后,在将其转换为基本数据类型
var s = 123
s = s.toString()
console.log(typeof s) //string
字符串方法
- charAt()
可以返回字符串中指定位置的字符
根据索引获取指定的字符 - charCodeAt()
获取指定为止字符的字符编码(Unicode编码) - String.formCharCode()
可以根据字符编码去获取字符 - indexOf()
可以检索一个字符串中是否含有指定内容
如果字符串中含有该内容,返回其第一次出现的索引,如果没有找到指定内容,返回-1
可以指定第二个参数,指定开始查找的位置 - split()
可以将一个字符串拆分为一个数组
需要一个字符串作为参数,将根据字符串去拆分数组 - toUpperCase()
将字符串转为大写并返回 - toLowerCase()
将字符串转为小写并返回
str = "Hello"
console.log(str.charAt(1)) //e
console.log(str.charCodeAt(2)) //108
console.log(String.fromCharCode(0x2692)) //⚒
console.log(str.indexOf("e")) //1
str1 = "abc,bcd,efg,hij"
console.log(str1.split(',')) //['abc', 'bcd', 'efg', 'hij']
正则表达式
- 正则表达式用于定义一些字符串的规则,计算机可以根据正则表达式来检查一个字符串是否符合规则
- 创建正则表达式的对象
var 变量 = new RegExp(“正则表达式”,“匹配模式”) - 构造函数中可以传递一个匹配模式作为第二个参数
i 忽略大小写
g 全局匹配模式 - 使用typeOf检查正则对象,返回object
- test()
使用这个方法可以用来检测一个字符串是否符合正则表达式规则
如果符合返回true,否则返回falsevar reg = new RegExp("a") //检查一个字符串中是否含有a var str = "abb" console.log(reg.test(str)) //true
- 使用字面量来创建正则表达式
var 变量 = /正则表达式/匹配模式
var reg = /a/i
使用字面量方式创建更加简单,使用构造函数更加灵活 - 使用|表示或者的意思
reg = /a|b|c/ - [ ]里的内容也是或的关系
[ab] == a|b
[a-z] 任意小写字母
[A-z] 任意字母和_
[^] 除了 - 量词
通过量词可以设置一个内容出现的次数
量词只对它前边一个内容起作用
{n}正好出现n次
{m,n} 出现m-n次
{m,} 出现m次或m以上
reg = /ab{3,4}c/ - +至少一个,相当于{1,}
- *0个或多个,相当于{0,}
- ?0个或一个,相当于{0,1}
- ^ 表示开头
- $ 表示结尾
// 手机号规则: 18912334586
// 1.以1开头
// 2.第二位3-9
// 3.三位以后任意数字9个
var phoneStr = "18912334586"
var phoneReg = /^1[3-9][0-9]{9}$/
// 电子邮件
// hello .nihao @ abc .com.cn
// 任意字母数字下划线 .任意字母数字下划线 @ 任意字母数字 .任意字母(2-5位) .任意字母(2-5位)
// \w{3,} (\.\w+)* @ [A-z0-9]+ (\.[A-z]{2,5}){1,2}
var emailReg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/
var email = "abc.hello@163.com"
console.log(emailReg.test(email)) //true
- 在正则表达式中使用\作为转义字符
\. 来表示.
\\ 来表示\
注意:使用构造函数时,由于他的参数是一个字符串,而\是字符串中转移字符,如果需要使用\则需要使用\\来代替 - \w 字母、数字、_
- \W 除了字母、数字、_
- \d 任意数字[0-9]
- \D 除了任意数字[0-9]
- \s 空格
- \S 除了空格
- \b 单词边界
- \B 除了单词边界
// 检查一个字符串是否含有child
var str = " hello child "
var reg = /\bchild\b/
console.log(reg.test(str)) //true
//去掉两侧空格
reg = /^\s* |\s*$/
str = str.replace(reg, "")
console.log(str) //hello child
正则相关方法
- split()
可以将一个字符串拆分为一个数组
方法中可以传递一个正则表达式作为参数,根据正则表达式去拆分
不指定全局匹配也会全部拆分 - match()
可以根据正则表达式从一个字符串中将符合条件内容提取出来
默认match只会找第一个符合条件的内容,找到后停止检索,可以设置正则表达式为全局匹配模式
match会将匹配到的内容封装到一个数组中,即使只查询到一个结果 - search()
可以搜索字符串中是否含有指定内容
有返回第一次出现的索引,没有返回-1
search只查找第一个,即使设置全局匹配也没有用 - replace()
可以将字符串中指定内容替换为新内容
默认只替换一个
var str = "1a2b3c4d5e6f7"
var result = str.split(/[A-z]/) //根据正则将字符串拆分为数组
console.log(result) //['1', '2', '3', '4', '5', '6', '7']
result = str.match(/[A-z]/g) //提取符合条件内容
console.log(result) // ['a', 'b', 'c', 'd', 'e', 'f']
str = "hello abc afc aec aac"
result = str.search(/a[a-z]c/) //搜索指定内容返回索引
console.log(result) //6
result = str.replace(/a/g, "@") //替换
console.log(result) //hello @bc @fc @ec @@c