笔记:02:JS

目录

1、变量命名规范
2、伪数组
3、DOM操作节点
4、获取元素的方法
5、this指向
6、事件绑定的几种方式
7、document.write与innerHTML的区别
8、获取焦点&失去焦点
9、数据类型
10、类型转换
11、检验数据类型
12、数组方法
13、字符串方法
14、对象
15、js的全局函数
16、js延迟加载
17、new操作符介绍
18、form
19、call、apply、bind
20、宽高
21、javascript 的本地对象,内置对象和宿主对象
22、window.onload与$(document)
23、存储
24、闭包概念、优缺点及使用场景
25、防抖、节流
26、原型链的理解
27、select
28、mouseover事件和mouseenter事件的区别
29、==
30、Ajax 原理是什么?如何实现?
31、用js判断页面刷新或关闭的方法(onbeforeunload与onunload事件)
32、String()和toString()的区别和应用
33、比较字符串:localeCompare
34、阻止事件冒泡

正文

1、变量命名规范
  • 变量名区分大小写,允许包含字母、数字、美元符号($)和下划线,但第一个字符不允许是数字,不允许包含空格和其他标点符号。
  • 禁止使用JavaScript关键词、保留字全名。
  • 驼峰命名。
2、伪数组 原文链接

伪数组:就是像数组一样有 length 属性,也有 0、1、2、3 等属性的对象,看起来就像数组一样,但不是数组。

伪数组转换为真数组:Array.prototype.slice.call(arguments)、Array.from(arguments) slice发音 slice解释

let val={
    "0":'haha',
    "1":'kaka',
    "2":"wawa",
    length:3
}
let newVal=Array.prototype.slice.call(val)
console.log(val)    // {0: "haha", 1: "kaka", 2: "wawa", length: 3}
console.log(newVal) // (3) ["haha", "kaka", "wawa"]
3、DOM操作节点
  • 1、创建新节点
    document.createElement():创建元素节点。
    document.createTextNode():创建文本节点。
    document.cloneNode():克隆节点。
  • 2、节点操作
    appendChild():添加
    removeChild():移除
    replaceChild():替换
    insertBefore():插入
  • 3、查找
    getElementsByTagName():通过标签名称查找
    getElementsByName():通过元素的name属性查找
    getElementById():通过元素id查找
4、获取元素的方法 原文链接
  • childNodes:当前元素的全部子节点。
  • parentNode:当前元素的父节点。
  • nextSibling:当前元素的下一个兄弟节点。
  • previousSibling:当前元素的上一个兄弟节点。
  • firstChild:当前元素的第一个节点。
  • lastChild:当前元素的最后一个节点。
5、this指向
  • 对象方法内部
var obj={
    name:"veb",
    say:function(){
        console.log(this.name) // veb
    }
}
obj.say();
  • 事件处理函数内部
btn.onclick=function(){
    console.log(this) // btn
    function f(){
        console.log(this);
    }
    f();//window
}
  • 构造函数内部
function fun(){
    console.log(this);
}
let fff=new fun() // fun
  • 普通函数内部
function fun(){
    console.log(this);
}
fun() // window
6、事件绑定的几种方式
  • 1、标签之中直接添加:onclick='fun()'
  • 2、js添加:元素.onclick=method
  • 3、ie9之前:元素.attachEvent('onclick',method)
    标准浏览器:元素.addEventListener('click',method,false)。(第三个参数默认false:在冒泡阶段执行指定事件;true:在捕获阶段执行事件)

双击事件:ondblclick

7、document.write与innerHTML的区别
  • document.write:重绘整个页面。
  • innerHTML:重绘页面的一部分。
8、获取焦点&失去焦点
<div class="block">
    <input id="inputs" type="text">
    <p id="text">请输入</p>
</div>

注:(1.拼写)
获取焦点:onfocus
失去焦点:onblur
获取input值:#inputs.value

9、数据类型
  • 基本数据类型:
    字符串、数值型、布尔型
  • 复合数据类型:
    对象、数组
  • 其他数据类型:
    函数、null、undefined
  • NaN的特点:
    NaN,即非数字值,是一个特殊的数值,属于Number类型。
    任何涉及NaN的操作,结果都为NaN。
    NaN与任何值都不等,包括NaN本身。
  • null:
    空。未定义。
  • undefined:
    没有。定义了,未赋值。
  • 注:双向非操作可以把字符串和数字转换为布尔值。console.log(!!2)
10、类型转换
  • 强制类型转换:
    转换成数值:Number(mix)、parseInt(string,radix)、parseFloat(string)
    转换成字符串:toString(radix)、String(mix)。toString()无法转换null和undefined。
    转换成布尔:Boolean(mix)
  • 隐式类型转换:
-
==
===
11、检验数据类型 原文链接

typeof、instanceof(验证真假)、constructor(验证真假)、object.prototype

  • typeof:例:typeof 'haha' // string 注:无法区分数组、对象、null:object
  • instanceof:例:'haha' instanceof String // false 注:区分数组、对象、函数
  • constructor:例:('haha').constructor === String // true
  • object.prototype:例:Object.prototype.toString.call('str').slice(8,-1) // String
12、数组方法
1、push:尾部添加。向数组的末尾添加一个或多个元素,并返回新的数组长度。原数组改变。
    let arr0 = [1, 2, 3]
    arr0.push('a', 'b') // [1, 2, 3, 'a', 'b']

2、pop:尾部删除。删除并返回数组的最后一个元素,若该数组为空,则返回undefined。原数组改变。
    let arr1 = [1, 2, 3, 4]
    arr1.pop() // [1, 2, 3]

3、unshift:头部添加。向数组的开头添加一个或多个元素,并返回新的数组长度。原数组改变。
    let arr2 = [1, 2, 3, 4, 5]
    arr2.unshift('a') // ["a", 1, 2, 3, 4, 5]

4、shift:头部删除。删除数组的第一项,并返回第一个元素的值。若该数组为空,则返回undefined。原数组改变。
    let arr3 = [1, 2, 3, 4, 5]
    arr3.shift() // [2, 3, 4, 5]

5、concat:合并数组。合并两个或多个数组,生成一个新的数组。原数组不变。
    let arr4 = [1, 2, 3, 4]
    let arr5 = arr4.concat(['a', 'b', 'c']) // [1, 2, 3, 4, "a", "b", "c"]

6、join:数组的每一项用指定字符连接形成一个字符串。默认连接字符为 “,” 逗号。
    let arr6 = [1, 2, 3, 4]
    let arr7 = arr6.join() // 1,2,3,4

7、reverse:将数组倒序。原数组改变。
    let arr8 = [1, 2, 3, 4, 6, 5]
    arr8.reverse() // [5, 6, 4, 3, 2, 1]

8、sort:对数组元素进行排序。按照字符串UniCode码排序,原数组改变。
    let arr9 = [4, 7, 2, 6, 3, 5, 8]
    // 从小到大
    let sort1 = function(a, b){
        return a - b
    }
    arr9.sort(sort1) // [2, 3, 4, 5, 6, 7, 8]
    // 从大到小
    let sort2 = function(a, b){
        return b - a
    }
    arr9.sort(sort2) // [8, 7, 6, 5, 4, 3, 2]
    // 按照数组对象中的某个值进行排序
    let arr10 = [
        {name: 'aaa', age: 10},
        {name: 'aaa', age: 9},
        {name: 'aaa', age: 20},
    ]
    let sort3 = function(params){
        return function sort4(a, b){
            return a[params] - b[params]
        }
    }
    arr10.sort(sort3('age')) // [{name: "aaa", age: 9}, {name: "aaa", age: 10}, {name: "aaa", age: 20}]

9、slice(start,end):从start开始,end之前结束,不到end;如果不给end值,从start开始到数组结束。start可以给负值,-1表示数组最后位置,-2表示倒数第二个,以此类推,顾前不顾后。
    let arr11 = [1, 2, 3, 4]
    let arr12 = arr11.slice( -3, -1) // [2, 3]

10、splice(index,howmany,arr1,arr2...):删除元素并添加元素,从index位置开始删除howmany个元素,并将arr1、arr2...数据从index位置依次插入。howmany为0时,则不删除元素。原数组改变。
    let arr13 = [1, 2, 3, 4]
    arr13.splice(1, 2, 'a', 'b') // [1, "a", "b", 4]

11、map(function):原数组的每一项执行函数后,返回一个新的数组。原数组不变。(注意该方法和forEach的区别)。
    let arr14 = [
        {name: 'aaa', age: 10},
        {name: 'bbb', age: 17},
        {name: 'ccc', age: 15},
    ]
    let arr15 = arr14.map(item=>{
        return item.age
    }) // [10, 17, 15]

12、forEach(function):用于调用数组的每个元素,并将元素传递给回调函数。(注意该方法和map的区别,若直接打印Array.forEach,结果为undefined)。
    let arr16 = [1, 2, 3, 4, 5]
    arr16.forEach(function(value,index,array){
        console.log(value) // 1 2 3 4 5
    })

13、filter(function):过滤数组中,符合条件的元素并返回一个新的数组。
    let arr17 = [1, 2, 3, 4, 5];
    let arr18 = arr17.filter(function(x){
        if(x>3){
            return true;
        }
    }) // [4, 5]

14、every(function):对数组中的每一项进行判断,若都符合则返回true,否则返回false。
    let arr19 = [1, 2, 3, 4, 5];
    let flag1 = arr19.every(function(x){
        return x>3
    }) // false

15、some(function):对数组中的每一项进行判断,若都不符合则返回false,否则返回true。
    let arr20 = [1, 2, 3, 4, 5];
    let flag2 = arr20.every(function(x){
        return x>3
    }) // true

16、reduce(function):接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
    let arr21 = [1, 2, 3, 4, 5];
    let total = arr21.reduce((a, b) => a + b) // 15

17、toString:将数组转换成字符串。

18、indexOf:返回当前元素在数组中的索引。

参考文件:https://www.cnblogs.com/hexinhui/p/9516544.html

13、字符串方法
1、concat:连接俩字符串
    let str0 = 'abcd'
    let str1 = 'efg'
    let str2 = str0.concat(str1) // "abcdefg"

2、charAt:得到指定索引位置的单字符
    let str3 = "abcdefg".charAt(4) // 'e'

3、charCodeAt:得到指定索引位置字符的Unicode值
    let str4 = "abcdefg".charCodeAt(4) // 101

4、indexOf:取当前字符串第一次出现的索引
    // indexOf()方法对大小写敏感,如果子字符串没有找到,返回-1。第二个参数表示从哪个下标开始查找,没有写则默认从下标0开始查找。
    let str5 = "abcdefg".indexOf('f') // 5

5、lastIndexOf:取当前字符串最后一次出现的索引
    // lastIndexOf()方法对大小写敏感,如果子字符串没有找到,返回-1。第二个参数表示从哪个下标开始查找,没有写则默认从最后一个字符处开始查找。
    let str6 = 'qqqweeee'.lastIndexOf('q') // 2

6、replace:找到'q'替换为'z'
    let str7 = 'qwerqwer'.replace('q', 'z') // 'zwerqwer'
    let reg = /q/g
    let str71 = 'qwerqwer'.replace(reg, 'z') // 'zwerzwer'

7、slice:返回字符串中提取的子字符串
    // 如果只有一个参数,则提取开始下标到结尾处的所有字符串
    // 两个参数,提取下标为2,到下标为5但不包含下标为5的字符串
    // 如果是负数,-1为字符串的最后一个字符。提取从下标-7开始到下标-2但不包含下标-2的字符串。前一个数要小于后一个数,否则返回空字符串
    let str8 = 'werafdcv'.slice(2, 5) // 'raf'
    参考文件:https://www.runoob.com/jsref/jsref-slice-string.html

8、substring:提取字符串中介于两个指定下标之间的字符。
    // 如果两个参数相等,返回长度为0的空串
    // substring()用法与slice()一样,但不接受负值的参数。
    let str9 = 'asdfgfghs'.substring(4, 5) // 'g'
    参考文件:https://www.runoob.com/jsref/jsref-substring.html

9、substr:从索引start开始取length个字符 , length不可小于0否则返回空字符串
    // 如果没有指定length,返回从下标开始处结尾处的所有字符串。
    let str10 = 'asdfgfghs'.substr(4, 2) // 'gf'
    参考文件:https://www.runoob.com/jsref/jsref-substr.html

10、search:在str01中搜索字符串"str" , 返回其第一个字符在str01中的索引
    let str11 = 'asdfqrewdf'.search('qre') // 4

11、valueOf:可返回字符串对象的原始值
    let str12 = 'asdf'.valueOf() // 'asdf'

12、split:将原字符串分割为一个数组对象,分隔符为逗号,参数为 空 空格 字符串
    // 第二个参数为返回数组的最大长度
    let str13 = 'fdsarwqetrq'.split('') // ["f", "d", "s", "a", "r", "w", "q", "e", "t", "r", "q"]

13、toLowerCase(): 把字符串转为小写,返回新的字符串。
    let str14 = 'AFBJdasff'.toLowerCase() // 'afbjdasff'

14、toUpperCase(): 把字符串转为大写,返回新的字符串。
    let str15 = 'AFBJdasff'.toUpperCase() // 'AFBJDASFF'
15、startsWith(string):用于检测字符串是否以指定的子字符串开始。如果是以指定的子字符串开头返回 true,否则 false。startsWith() 方法对大小写敏感。
    var str = "Hello world, welcome to the Runoob.";
    var n = str.startsWith("Hello"); // true
    参考文件:http://www.w3school.me/jsref/jsref-startswith.html
14、对象
  • 1、Date对象:
    (1)getFullYear():年
    (2)getMonth():月(需要+1)
    (3)getDate():日
    (4)getHours():时
    (5)getMinutes():分
    (6)getSeconds():秒
    (7)getTime():时间戳
  • 2、Math对象:
    (1)round():四舍五入。
    (2)floor():向下取整。
    (3)random():0-1随机数。
    (4)max():两个给定的数中较大的数。
    (5)min():两个给定的数中较小的数。
    (6)abs():绝对值。
  • 3、内置函数:Date.now():返回自1970年1月1日00:00:00 UTC以来经过的毫秒数,也就是时间戳
15、js的全局函数
  • escape:可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。ECMAScript反对使用该方法,应使用decodeURI()和decodeURIComponent()替代它。
  • parseFloat:函数可解析一个字符串,并返回一个浮点数。该函数指定字符串中的首个字符是否是数字。如果是,则对字符串进行解析,直到到达数字的末端为止,然后以数字返回该数字,而不是作为字符串。
  • eval:可计算某个字符串,并执行其中的js代码。 原文链接
  • setTimeout
  • alert
16、js延迟加载 原文链接
  • 1、script标签的defer='defer',表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。 原文链接
  • 2、script标签的async,不让页面等待脚本下载和执行,从而异步加载页面其他内容。
  • 3、动态创建script标签。
  • 4、把js外部引入的文件放到页面底部,来让js最后引入,从而加快页面加载速度。
  • 5、jQuery的getScript方法。例:$.getScript('other.js',function(){ console.log('脚本加载完成回调函数') })
17、new操作符介绍
  • 1、创建一个空对象,并且this变量引用该对象,同时还继承了该函数的原型。
  • 2、属性和方法被加入到this引用的对象中。
  • 3、新创建的对象由this所引用,并且最后隐式的返回this。
18、form

form.elements:访问表单中的表单元素

19、call、apply、bind 原文链接

改变this指向。

  • call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,因此后面还需要()来进行调用才可以。
  • call和bind后面的参数与say方法中是一一对应的,而apply的第二个参数是一个数组,数组中的元素是和say方法中一一对应的。
  • call和apply在调用时改变this指向。bind是在定义时改变this指向。
let obj = {
    name: ‘jack‘
}

function People(name) {
    this.name = name;
}

People.prototype = {
    sayHi(name) {
        console.log(`Hi,${name}~`)
    }
}

let child = new People(‘rose‘);

child.sayHi.call(obj, ‘Sofia‘);
child.sayHi.apply(obj, [‘Sofia‘]);

let bind = child.sayHi.bind(obj, ‘Sofia‘);
bind();
20、宽高
  • 获取浏览器宽高:
    window.innerWidth;window.innerHeight
  • 窗口滚动高度:
    非IE:document.documentElement.scrollTop
    IE:document.body.scrollTop
  • 元素到文档顶部的高度:
    元素.offsetTop
  • 元素到文档顶部的左侧偏移量:
    元素.offsetLeft
  • 鼠标坐标:
    e.clientX;e.clienetY
  • 浏览器屏幕信息:screen
    screen.width:屏幕区域的实际宽度
    screen.height: 屏幕区域的实际高度
    screen.availWidth:显示屏幕的可用宽度(减去界面特性,比如窗口任务栏)
    screen.availHeight:显示屏幕的可用高度(减去界面特性,比如窗口任务栏)
  • 获取非行内样式:
    非IE:getComputedStyle(元素,false)['fontSize']
    IE:元素.currentStyle['padding']
21、javascript 的本地对象,内置对象和宿主对象 原文链接
  • 本地对象:array obj regexp 等可以 new 实例化。
  • 内置对象:gload Math 等不可以实例化的。
  • 宿主对象:浏览器自带的document,window等。
22、window.onload与$(document).ready()
  • window.onload:必须等待网页全部加载完毕(包括图片等),然后再执行包裹代码。
    如果同一个页面上面有多个window.onload方法(包括关联js文件中),只会执行最后一个window.onload,也就是向上覆盖
    例:window.onload = function(){ console.log(111) }
$(document).ready():需要等待网页中的DOM结构加载完毕,就能执行包裹代码。
可以执行多次,不会覆盖
简写:$(function(){})
例:$(document).ready(()=>{ console.log(222) })
23、存储 原文链接
  • 本地存储:
    cookie:
    set:例:document.cookie='value=10;expires=24 * 60 * 60 * 1000 * 1'。注:expires不设置时,cookie在浏览器关闭后删除。
    get:document.cookie
    del:document.cookie='value=" ";expires="-1"'。过期时间设置为负值即可。
    1、每个特定域名下最多生成的cookie个数有限。 原文链接
    2、ie和OPera会清理近期最少使用的cookie,Firefox会随机清理cookie。
    3、每个cookie长度不能超过4kb,否则会被截掉。
    localStorage:没有过期时间,如果不手动清除,数据就永远不会过期,一直保存在浏览器中。
    sessionStorage:关闭当前标签页,即失效。
  • 服务器存储:
    session:
    session数据放在服务器上。
    cookie数据存放在客户的浏览器上,session数据放在服务器上。
    cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
    session会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
    单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
    建议将登录信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。
    session保存在服务器,客户端不知道其中的信息;cookie保存在客户端,服务器能够知道其中的信息。
    session中保存的是对象,cookie中保存的是字符串。
    session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到,而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的。
    session需要借助cookie才能正常工作。如果客户端完全禁止cookie,session将失效。 但是如果服务器端启用了url编码,也就是用 URLEncoder.encode()把所有的url编码了,则会在url后面出现如下类似的东西 index.jsp:jsessionid=fdsaffjdlks;jaf;lkdjsf 服务器通过这个进行session的判断。
    Cookie支持跨域名访问,例如将domain属性设置为“.biaodianfu.com”,则以“.biaodianfu.com”为后缀的一切域名均能够访问该Cookie。跨域名Cookie如今被普遍用在网络中,例如Google、Baidu、Sina等,而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。仅运用Cookie或者仅运用Session可能完成不了理想的效果。这时应该尝试一下同时运用Cookie与Session。Cookie与Session的搭配运用在实践项目中会完成很多意想不到的效果。
24、闭包概念、优缺点及使用场景 原文链接
  • 概念:
    闭包是指有权访问另外一个函数作用域中的变量的函数。
  • 1、作用:
    读取与函数内部的变量值;
    让这些变量值始终保存着(在内存中)。
  • 2、优点:
    (1)可以重复使用变量,并且不会造成变量污染。(全局变量可以重复使用,但是容易造成变量污染。局部变量仅在局部作用域内有效,不可以重复使用,不会造成变量污染。闭包结合了全局变量和局部变量的优点。)
    (2)可以用来定义私有属性和私有方法。
  • 3、缺点:
    比普通函数更占用内存,会导致网页性能变差,在IE下容易造成内存泄露。(因为闭包就是能够访问外部函数变量的一个函数,而函数是必须保存在内存中的对象,所以位于函数执行上下文中的所有变量也需要保存在内存中,这样就不会被回收,如果一旦循环引用或创建闭包,就会占据大量内存,可能会引起内存泄漏。)
  • 4、使用场景:
    封装功能时(需要使用私有的属性和方法),函数防抖、函数节流、函数柯里化、给元素伪数组添加事件需要使用元素的索引值。
25、防抖、节流
  • 1、防抖:
    概念:就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。(通俗一点:在一段固定的时间内,只能触发一次函数,在多次触发事件时,只执行最后一次。)
    使用时机:搜索功能,在用户输入结束以后才开始发送搜索请求,可以使用函数防抖来实现。
  • 2、节流:
    概念:就是限制一个函数在一定时间内只能执行一次。
    使用时机:改变浏览器窗口尺寸,可以使用函数节流,避免函数不断执行;滚动条scroll事件,通过函数节流,避免函数不断执行。
  • 3、区别:
    设定一个间隔时间为一秒,在一分钟内,不断的移动鼠标,让它触发一个函数,打印一些内容。
    函数防抖:会打印1次,在鼠标停止移动的一秒后打印。
    函数节流:会打印60次,因为在一分钟内有60秒,每秒会触发一次。
    总结:节流是为了限制函数的执行次数,而防抖是为了限制函数的执行时机。
26、原型链的理解

原型链主要用于继承,每一个普通对象都有proto属性,指向它构造函数的原型对象,当访问对象的属性或方法时,会先在对象本身查找,如果没有,则沿着proto属性往上一级查找,一直找到null为止。

27、select

onchange事件

28、mouseover事件和mouseenter事件的区别

mouseover支持事件冒泡

29、==
const a = {
    i: 1,
    toString: function () {
        return a.i++;
    }
}

if (a == 1 && a == 2 && a == 3) {
    console.log('Hello World!');
}
30、Ajax 原理是什么?如何实现?
image.png
  • 封装
//封装一个ajax请求
function ajax(options) {
    //创建XMLHttpRequest对象
    const xhr = new XMLHttpRequest()


    //初始化参数的内容
    options = options || {}
    options.type = (options.type || 'GET').toUpperCase()
    options.dataType = options.dataType || 'json'
    const params = options.data

    //发送请求
    if (options.type === 'GET') {
        xhr.open('GET', options.url + '?' + params, true)
        xhr.send(null)
    } else if (options.type === 'POST') {
        xhr.open('POST', options.url, true)
        xhr.send(params)

    //接收请求
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            let status = xhr.status
            if (status >= 200 && status < 300) {
                options.success && options.success(xhr.responseText, xhr.responseXML)
            } else {
                options.fail && options.fail(status)
            }
        }
    }
}
  • 使用
ajax({
    type: 'post',
    dataType: 'json',
    data: {},
    url: 'https://xxxx',
    success: function(text,xml){//请求成功后的回调函数
        console.log(text)
    },
    fail: function(status){////请求失败后的回调函数
        console.log(status)
    }
})

参考文件:Ajax 原理是什么?如何实现?

31、用js判断页面刷新或关闭的方法(onbeforeunload与onunload事件) 参考文件
  • 页面加载时只执行onload
  • 页面关闭时先执行onbeforeunload,最后onunload
  • 页面刷新时先执行onbeforeunload,然后onunload,最后onload。
32、String()和toString()的区别和应用 参考文件
  • 应用
    String()和toString()都是将其他类型的变量转换为字符串类型。
let a =1;
let b = 123;
String(a); // '1'
typeOf(a); // String
typeOf(b); //Number
b.toString(); // '123'
typeOf(b); //String;
  • 区别
    toString()无法转换null和undefined
let a;
let b=null;
a.toString();//Uncaught TypeError: Cannot read property 'toString' of undefined
b.toString(); //Uncaught TypeError: Cannot read property 'toString' of null
String(a); //"undefined"
String(b);//"null"
33、比较字符串:localeCompare 参考原文

js提供了字符串的对比方法localeCompare(),该方法返回的是一个数字用来表示一个参考字符串和对比字符串是排序在前,在后或者相同。该方法基本不单独使用,大部分时间是配合字符串排序使用的。

  • 一、语法:
string.localeCompare(targetString,locales,options);
  • 二、参数
    targetString:对比字符串
    locales:看MDN上的解释是用来表示一种或多种语言或区域的一个符合 BCP 47 标准的字符串或一个字符串数组,我个人的理解是,指定一系列字符的顺序,提供给对比字符串的对比顺序,就好比我们通过26个字母的顺序就知道a,c的排序的顺序。
    options:是单个活对象组成的多个参数,主要的可以到MDN去查。
  • 三、返回值:返回值是一个数字,目前的主流浏览器都返回的是1、0、-1三个值,但是也有其他情况,所以不可以用绝对的值等于1、-1这种去判断返回的结果
    返回值大于0:说明当前字符串string大于对比字符串targetString
    返回值小于0:说明当前字符串string小于对比字符串targetString
    返回值等于0:说明当前字符串string等于对比字符串targetString
  • 四、方法的调用

1、方法的单独调用:就是简单的去对比两个字符串,查看其返回值就好。

var str = 'aaa',
    strCom = 'bbb',
    strCom2 = 'aaa';
str.localeCompare(strCom); //-1
strCom.localeCompare(str); //1
str.localeCompare(strCom2); //0

2、配合排序的调用:该方法用来单独比较字符串的情况比较少,大多数情况下是配合字符串的排序下使用的。

ar strList = ['cc', 'ee', 'ca', 'aa'];
 
strList.sort((a, b) => {
    return a.localeCompare(b);
});
console.log(strList);   //["aa", "ca", "cc", "ee"]
34、阻止事件冒泡参考文件
  • stopPropagation:event.stopPropagation(),阻止事件冒泡。
  • stopImmediatePropagation:event.stopImmediatePropagation();,阻止事件冒泡并且阻止该元素上同事件类型的监听器被触发。例如:

1、没有阻止事件冒泡:

import React, { Component } from 'react';
export default class App extends Component {
  componentDidMount() {
    let parent = document.getElementById('parent');
    let child = document.getElementById('child');
    parent.addEventListener('click', this.parentClick);
    child.addEventListener('click', this.childClick1);
    child.addEventListener('click', this.childClick2);
  }
  childClick1 = (e)=> {
    console.log('child1');
  }
  childClick2 = (e)=> {
    console.log('child2');
  }
  parentClick = ()=> {
    console.log('parent');
  }

  render() {
    return (
      <div id='parent'>
        <button id='child'>click me!</button>
      </div>
    );
  }
}

// 控制台输出为:child1 child2 parent

2、使用stopPropagation阻止事件冒泡:

import React, { Component } from 'react';
export default class App extends Component {
  componentDidMount() {
    let parent = document.getElementById('parent');
    let child = document.getElementById('child');
    parent.addEventListener('click', this.parentClick);
    child.addEventListener('click', this.childClick1);
    child.addEventListener('click', this.childClick2);
  }
  childClick1 = (e)=> {
    console.log('child1');
    e.stopPropagation();
  }
  childClick2 = (e)=> {
    console.log('child2');
  }
  parentClick = ()=> {
    console.log('parent');
  }

  render() {
    return (
      <div id='parent'>
        <button id='child'>click me!</button>
      </div>
    );
  }
}
// 控制台输出为:child1 child2

3、使用stopImmediateStopPropagation阻止事件冒泡:

import React, { Component } from 'react';
export default class App extends Component {
  componentDidMount() {
    let parent = document.getElementById('parent');
    let child = document.getElementById('child');
    parent.addEventListener('click', this.parentClick);
    child.addEventListener('click', this.childClick1);
    child.addEventListener('click', this.childClick2);
  }
  childClick1 = (e)=> {
    console.log('child1');
    e.stopImmediatePropagation();
  }
  childClick2 = (e)=> {
    console.log('child2');
  }
  parentClick = ()=> {
    console.log('parent');
  }
  render() {
    return (
      <div id='parent'>
        <button id='child'>click me!</button>
      </div>
    );
  }
}
// 控制台输出为:child1

可以看到 #child节点上绑定了2个click事件,如果只使用stopPropagation是只能阻止事件冒泡至其父节点,而stopImmediatePropagation既能阻止事件冒泡至父节点,也能阻止当前节点上其他同类型事件的触发。

值得注意的是,这里我是通过addEventListener绑定事件,而不是通过React的onClick绑定事件。
这是因为直接使用addEventListener绑定的事件是直接绑定在真实DOM节点上的,而React的onClick绑定的事件是合成事件,没有绑定在真实DOM上,而是在document处监听所有支持的事件,当事件冒泡至document时,React将事件内容封装并交由真正的处理函数运行。
React中event事件是syntheticEvent(合成事件),合成事件有对原生stopPropagation进行封装,但没有对stopImmediatePropagation进行封装,在react的事件中没有stopImmediatePropagation函数。但可以通过event.nativeEvent.stopImmediatePropagation进行调用。

100、面试题原文链接
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容

  • 万丈高楼,始于垒土,所以基础语法就是我们技术的根基,今天我们来聊聊JS的基础语法温馨提示:文章结构如下,阅读完可能...
    摸着石头过河_崖边树阅读 277评论 0 0
  • js语言特点(基于ES的语法): ** js的变量类型取决于值的类型 ** 1.脚本语言2.基于对象:3.简单 ...
    A囡囡_1313阅读 238评论 0 0
  • 1、程序就是一堆数据+处理数据的指令。数据和指令是程序永恒不变的主题 2、数据的五大类型 字符型:string 数...
    夜幕小草阅读 336评论 0 0
  • 方便起见不分parameter[形参,出现在函数定义中]和argument[实参,其值为传入函数的值],一律当作a...
    东月三二阅读 381评论 0 0
  • 1.js当中有哪些数据类型 5个基础:字符串,布尔,数值,null,undefined,1个复杂:Object在e...
    林不羁吖阅读 257评论 0 0