一,数据类型(6种)
基本类型:
number,string,boolean,null,undefined
复合类型:
object
区别:
存储位置不同,基本类型存储在栈(stack)中,复合类型存储在堆(heap)中
访问机制不同,javascript不允许直接访问堆内存中的对象,在访问一个对象时,首先得到的是这个对象在堆内存中的地址,然后按照这个地址去获得对象的值,就是所谓的按引用访问;而基本数据类型的值则可以直接访问得到
复制变量时的不同,在将一个保存着原始值的变量复制给另一个变量时,会将原始值的副本赋值给新变量,此后这两个变量是完全独立的,他们只是拥有相同的value而已。复合类型则是会把内存地址赋值给新变量
参数传递时的不同,
1)基本类型:只是把变量里的值传递给参数,之后参数和这个变量互不影响。
2)复合类型:对象变量它里面的值是这个对象在堆内存中的内存地址,因此它传递的值也就是这个内存地址,这也就是为什么函数内部对这个参数的修改会体现在外部的原因了,因为它们都指向同一个对象。
二,字符串方法
1.与数组相关的方法:
#split
var str = 'abc-def-hij'
str.split('-') //返回数组 ['abc', 'def', 'hij']
2.切割方法
#substring,slice
substring(start, end) //返回的结果不包括end位置的字符,如果没有end位置,默认返回start位置到字符串的最后 一位
slice(start, end) //和substring的返回规则一样
3.与位置相关的方法
#charAt,indexOf,lastIndexof
var str = 'abcdefga'
str.charAt(0) //'a'
str.indexOf('b') //1
str.lastIndexOf() // 7
4.转换大小写方法
#toUpperCase,toLowerCase
var str = 'abcdefg'
str.toUpperCase() //'ABCDEFGA' 原字符串不变,str仍然是abcdefga
str.toLowerCase()
5.与正则表达式相关的方法
replace,search,match
#replace
var p = 'The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?';
var regex = /dog/gi;
console.log(p.replace(regex, 'ferret'));
// "The quick brown fox jumped over the lazy ferret. If the ferret reacted, was it really lazy?"
#search
str.search(regexp)
如果传入一个非正则表达式对象,则会使用 new RegExp(obj) 隐式地将其转换为正则表达式对象。如果匹配成功,则 search() 返回正则表达式在字符串中首次匹配项的索引。否则,返回 -1
#match
stringObject.match(searchvalue)
stringObject.match(regexp)
如果传入一个非正则表达式对象,则会使用 new RegExp(obj) 隐式地将其转换为正则表达式对象。
如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。
三,数组方法
1.与字符串相关的方法
#join什么都不传,默认用逗号分隔
var arr = [1, 2, 3]
arr.join() //'1,2,3'
arr.join('') //'123'
2.栈和队列方法
#shift,unshift,pop,push(都会使原数组发生改变)
栈是一种后进先出的数据结构(pop和push模拟),队列的访问规则则是先进先出(push和shift模拟)
3.数组排序方法
#sort,reverse(都会使原数组发生改变)
var arr = [1, 2, 3]
arr.sort() //默认情况下按字符串升序排列数组
arr.sort(fn(a, b) {...}) //传入一个函数,这个函数可以传入前后比较的两个元素,如果返回正数则交换位置,返 回负数或者0,不交换位置
reverse用于反转数组的顺序
4.数组拼接方法
#concat (不影响原数组)
var arr = [1, 2, 3]
arr.concat(3, 4) //[1, 2, 3, 3, 4]
5.切割方法
#slice(不影响原数组), splice(影响原数组)
#slice(start, end) end位置的元素不包含
var arr = [1, 2, 3]
arr.slice(0) //[1, 2, 3]
arr.slice() //[1, 2, 3]
#splice
var arr = [1, 2, 3]
arr.splice() //[1, 2, 3],原数组=>[]
6.与位置相关的方法
#indexOf
var arr = [1, 2, 3]
arr.indexOf(1) // 0 返回元素在数组里的位置
7.与遍历相关的方法
#forEach,map,some,every,reduce
四.事件方法
在一个元素上注册事件,有两种方法:
目标元素.(on+事件类型)
非IE:目标元素.addEventListener(事件类型, 函数名), IE:目标元素.attachEvent(on+事件类型, 函数名)
第一种方法注册事件,后面注册的事件会把前面的覆盖掉,解绑方式:目标元素.(on+事件类型)=null
第二种注册事件的方式不会把之前注册的事件覆盖,非IE解绑方式:目标元素.removeEventListener(t事件类型, 函数名),IE:detachEvent(on+事件类型, 函数名)
注意:一般情况下会选择第二种方法绑定事件,以确保不影响以前绑定过的事件
其他js代码片段分享
1.解决精度问题 0.1 + 0.2 = 0.3000000000004
解决:先升幂,再降幂
function add (a, b) {
var r1 = ('' + a).split('.')[1].length
var r2 = ('' + b).split('.')[1].length
var m = Math.pow(10, Math.max(r1, r2))
return (a * m + b * m) / m
}
2.改变一个请求中的参数
//给url添加参数
function changeURLArg (url, key, val) {
var question_mark = url.indexOf('?')
var hashtag = url.indexOf('#')
var arr = []
var paramArr = []
var obj = {}
var str = ''
if (hashtag === -1) { //首先考虑#不存在的情况
if (question_mark > -1) {
arr = url.split('?')
paramArr = arr[1].split('&')
for (var i = 0; i < paramArr.length; i++) {
var tmp = paramArr[i].split('=')
if (tmp[0] === key) {
tmp[1] = val
}
obj[tmp[0]] = tmp[1]
}
var str = ''
for (var k in obj) {
str += '&' + k + '=' + obj[k]
}
if (obj[key] === undefined) {
str += '&' + key + '=' + val
}
return arr[0] + '?' + str.substring(1)
} else {
return url + '?' + key + '=' + val + '#' + arr[1]
}
} else { //#存在的情况
if (question_mark === -1) {
arr = url.split('#')
return arr[0] + '?' + key + '=' + val + '#' + arr[1]
} else {
if (question_mark < hashtag) {
arr = url.split('?')
var tmp = arr[1].split('#')
paramArr = tmp[0].split('&')
paramArr.forEach(s => {
var t = s.split('=')
var k = t[0]
obj[k] = t[1]
})
for (var i in obj) {
if (i === key) {
obj[i] = val
}
str += '&' + i + '=' + obj[i]
}
if (obj[key] === undefined) {
str += '&' + key + '=' + val
}
return arr[0] + '?' + str.substring(1) + '#' + tmp[1]
} else {
arr = url.split('#')
return arr[0] + '?' + key + '=' + val + '#' + arr[1]
}
}
}
}
3.大数相加,考虑js的number溢出问题
//大数相加,整数和小数皆可
function big (a, b) {
a += ''
b += ''
var arr = a.split('.')
var brr = b.split('.')
if (!arr[1]) arr[1] = '0'
if (!brr[1]) brr[1] = '0'
var a0 = arr[0]
var a1 = arr[1]
var b0 = brr[0]
var b1 = brr[1]
var i = 0
var len
var result = ''
var tmp = 0
var sum = 0
var lack = [Math.abs(a0.length - b0.length), Math.abs(a1.length - b1.length)]
if (a1.length >= b1.length) {
len = a1.length
for (; i < lack[1]; i++) {
b1 = b1 + 0
}
} else {
len = b1.length
for (; i < lack[1]; i++) {
a1 = a1 + 0
}
}
var r1 = addStr(a1, b1, len)
if (a0.length >= b0.length) {
len = a0.length
for (i = 0; i < lack[0]; i++) {
b0 = 0 + b0
}
} else {
len = b0.length
for (i = 0; i < lack; i++) {
a0 = 0 + a0
}
}
var r0 = addStr(a0, b0, len, r1.tmp)
if (r0.tmp) {r0.result = r0.tmp + r0.result}
if (r1.result === 0) return r0.result
result = r0.result + '.' + r1.result
return result
}
function addStr (a, b, len, tmp) {
var sum = 0
tmp = tmp || 0
var result = ''
for (var j = len - 1; j >= 0; j--) {
sum = (+a[j]) + (+b[j]) + tmp
if (sum >= 10) {
tmp = 1
result = sum - 10 + result
} else {
tmp = 0
result = sum + result
}
}
return {result: result, tmp: tmp}
}
4.事件模型模拟
function EventEmiter () {
let that = this
let tmp
this.cache = {}
this.on = function (type, fn) {
tmp = this.cache
let name = type.split('.')
if (typeof fn !== 'function') return
for (let i = 0; i < name.length; i++) {
// debugger
if (i === name.length - 1) {
if (tmp[name[i]]) {
tmp[name[i]].fn.push(fn)
} else {
tmp[name[i]] = {}
tmp[name[i]].fn = [fn]
}
continue
}
if (tmp[name[i]]) {
tmp = tmp[name[i]]
continue
} else {
tmp[name[i]] = {}
tmp[name[i]].fn = []
}
this.cache
tmp = tmp[name[i]]
}
this.cache
}
this.trigger = function (type) {
tmp = this.cache
let name = type.split('.')
for (let i = 0; i < name.length; i++) {
tmp = tmp[name[i]]
}
tmp.fn.forEach(method => {
method.apply(that, [].slice.call(arguments, 1))
})
}
this.off = function (type) {
tmp = this.cache
let name = type.split('.')
for (let i = 0; i < name.length; i++) {
// debugger
if (tmp[name[i]] && i === name.length - 1) {
delete tmp[name[i]]
} else if (tmp[name[i]] && i !== name.length - 1) {
tmp = tmp[name[i]]
continue
} else {
return
}
}
}
}
网友评论