顾名思义js笔记喽
所有记录再此的都为已经理解的内容。
1.常见的浏览器内核
- Trident 内核:IE, 360,搜狗浏览器 MaxThon、TT、The World,等。[又称 MSHTML]
- Gecko 内核:火狐,FF,MozillaSuite / SeaMonkey 等
- Presto 内核:Opera7 及以上。[Opera 内核原为:Presto,现为:Blink]
- Webkit 内核:Safari,Chrome 等。 [ Chrome 的:Blink(WebKit 的分支)]
2.mouseenter 和 mouseover 的区别
mouseenter
:当鼠标移动到元素或者子其元素上触发,只会触发一次。在子元素间移动也不会再次触发(不会冒泡),对应 mouseout。mouseover
:当鼠标移动到元素或者子其元素上触发,可以触发多次。移如其他子元素会再次触发(会冒泡),对应 mouseleave。
3.正则的使用
字母开头,然后数字或者字母,长度3到10
var reg=new RegExp("^[a-zA-Z][a-zA-Z0-9]{3,10}$"); console.log(reg.test("asdasd232323"));
4.JavaScript 里有哪些数据类型,解释清楚 null 和 undefined,解释清楚原始数据类型和引用数据类型。比如讲一下 1 和 Number(1)的区别
基本类型(原始数据类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
引用类型:对象(Object)、数组(Array)、函数(Function)。
PS:Symbol是ES6新加入的,凡是属性名属于Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
null 是表示缺少的标识,指示变量未指向任何对象。把 null 作为尚未创建的对象,也许更好理解。
undefined 是一个声明未定义的变量的初始值,或没有实际参数的形式参数。
1.存储位置不同
:原始数据类型存储在栈(stack)中,占据空间小,大小固定,被频繁使用的数据,所以存储在栈中;
引用数据类型直接存储在堆中,占据空间大,大小不固定,如果存储在栈中,将会影响程序运行的性能,引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后,从堆中获得实体。2.传值方式
:原始数据类型按值传递,方法操作无法改变数值,每次看似对值的修改操作,其实都是创建新的值。
引用类型按照引用传递,它的值是可以被修改的。3.两种类型被用作形参和实参的区别
:原始数据类型
var a = 3; function add(param){ param += 3; return param; } console.log(a); console.log(add(a)); console.log(a);结果:
3 6 3
引用数据类型
var a = []; function add(param){ param[0]=1; return param; } console.log(a); console.log(add(a)); console.log(a);结果:
[] [1] [1]
js中有三个包装对象:对象中有一类是Number, String, Boolean这三个对象,分别对应数字、字符串、布尔类型,我们称它们为包装对象或包装类型(Wrappers)
var a1 = new Number(123); var a2 = new String('abc'); var a3 = new Boolean(true); console.log(typeof a1); console.log(typeof a2); console.log(typeof a3); console.log(a1==123); console.log(a1===123);结果:
object object object true false
5.prototype、__proto__与constructor,原型链的理解(这部分内容较多慢慢完善)
①__proto__和constructor属性是对象所独有的;② prototype属性是函数所独有的。因为js中函数也是对象,所以函数也有__proto__和constructor。
个人理解,每一个对象都有原型。假设当你访问对象的a属性时,先查看对象本身是否存在a属性(obj.a)。如果不存在则搜索原型(obj.__proto__.a),如果原型中不存在,就去搜索原型的原型(obj.__proto__.__proto__.a),直到搜索到a或者__proto__为null时,搜索结局。这一整条的搜索过程就叫做
原型链
。
给已有的对象增加属性或者方法。使用obj.prototype.属性或方法名。
6.this
关于this指向我学到了一招
var a = 10; function test(){ return this.a; } //test() 理解成 test.call(window)的语法糖 console.log(test()) //10 var b = { a:20, test(){ return this.a; } } //b.test() 理解成 b.test.call(b)的语法糖 console.log(b.test()) //20
7.apply和 call 什么含义,什么区别?
两个方法都是提供新的 this 值给当前调用的函数/方法。你可以使用 call 来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。
区别只有一个就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。
8.实现一个方法,使得:add(2, 5) 和 add(2)(5) 的结果都为 7
function add(a,b){ if(arguments.length==1){ return function(c){ return a+c; } }else{ return a+b; } } console.log(add(1,2)); //3 console.log(add(1)(2)); //3
9.alert(1 && 2) 和 alert(1 || 0) 的结果
a&&b 如果a为真,返回b。a为假,返回a。
a||b 如果a为真,返回a。a为假,返回b。
10.以下代码输出结果。
var out = 25, inner = { out: 20, func: function () { var out = 30; return this.out; } }; console.log((inner.func, inner.func)()); console.log(inner.func()); console.log((inner.func)()); console.log((inner.func = inner.func)());
第一个输出:知识点是逗号运算符。(匿名函数)() ,匿名函数this指向为window 所以最后输出 25。
第二个输出:正常执行 this指向inner 输出 20。
第三个输出:同上
第四个输出:知识点等号运算,就是返回运算结果。也就是右边的inner.func,也是匿名函数所以结果同1。
11.以下代码输出结果。
if (!("a" in window)) { var a = 1; } alert(a);
这道题需要先了解三个部分
1.所有全局变量都是window的属性,所以var a=1;等同于window.a=1;
2.变量提升,变量声明被提升到作用域的顶端。
3.这道题声明被提升了可是赋值并没有。
综上所述本题可以转换为
var a ; if (!("a" in window)) { a = 1; } alert(a);
!("a" in window)
检测window是否存在a,因为变量提升所以a一直存在于window。赋值语句永远无法执行,所以结果为undefined。
12.以下代码输出结果。
function a(x) { return x * 2; } var a; alert(a);
这道题很简单变量生命在函数声明之前,所以可以转换成以下代码。
var a; function a(x) { return x * 2; } alert(a);
所以结果就是
function a(x) { return x * 2; }
13.从敲入 URL 到渲染完成的整个过程,包括 DOM 构建的过程,说的约详细越好
简单版本
1.用户输入 url 地址,浏览器根据域名寻找 IP 地址
2.浏览器向服务器发送 http 请求,如果服务器段返回以 301 之类的重定向,浏览器根据相应头中的 location 再次发送请求
3.服务器端接受请求,处理请求生成 html 代码,返回给浏览器,这时的 html 页面代码可能是经过压缩的
4.浏览器接收服务器响应结果,如果有压缩则首先进行解压处理,紧接着就是页面解析渲染
5.解析渲染该过程主要分为以下步骤:解析 HTML、构建 DOM 树、DOM 树与 CSS 样式进行附着构造呈现树
6.布局
7.绘制
详细版本
这部分内容较多,先记录,之后慢慢啃。
详细版本
14.JS 识别不同浏览器信息
function myBrowser() { var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 var isOpera = userAgent.indexOf("Opera") > -1; if (isOpera) { return "Opera" }; //判断是否Opera浏览器 if (userAgent.indexOf("Firefox") > -1) { return "Firefox"; } //判断是否Firefox浏览器 if (userAgent.indexOf("Chrome") > -1) { return "Chrome"; } //判断是否Google浏览器 if (userAgent.indexOf("Safari") > -1) { return "Safari"; } //判断是否Safari浏览器 if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera) { return "IE"; }; //判断是否IE浏览器 }
15.document.write 和 innerHTML 的区别
- document.write 是直接写入到页面的内容流,如果在写之前没有调用 document.open, 浏览器会自动调用
open。每次写完关闭之后重新调用该函数,会导致页面被重写。 - innerHTML 则是 DOM 页面元素的一个属性,代表该元素的 html 内容。你可以精确到某一个具体的元素来进行更改。如
果想修改document 的内容,则需要修改 document.documentElement.innerElement。 - innerHTML 将内容写入某个 DOM 节点,不会导致页面全部重绘。
- innerHTML 很多情况下都优于 document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。
- document.write 是重写整个 document, 写入内容是字符串的 html;innerHTML 是 HTMLElement
的属性,是一个元素的内部 html 内容
16.new 操作符具体干了什么呢 ?
创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
属性和方法被加入到 this 引用的对象中。
新创建的对象由this 所引用,并且最后隐式的返回 this 。
16.JSON 的了解?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
它是基于 JavaScript 的一个子集。
数据格式简单,易于读写,占用带宽小。
格式:采用键值对。例如:{ “age‟: ‟12‟, ”name‟: ‟back‟ }
17.合并数组
1.concat
var array1 = [1, 2, 3]; var array2 = [4, 5, 6]; console.log(array1.concat(array2)); // [1,2,3,4,5,6];
2.Array.prototype.push.apply()
var array1 = [1, 2, 3]; var array2 = [4, 5, 6]; array1.push.apply(array1, array2); console.log(array1); // [1, 2, 3, 4, 5, 6]
3.a.push(...[1,2,3,4])
var array1 = [1, 2, 3]; var array2 = [4, 5, 6]; array.push(...array2); console.log(array1); // [1, 2, 3, 4, 5, 6]
4.for循环不写例子了
18.打乱数组元素的顺序
var list = [1, 2, 3]; console.log(list.sort(function() { return Math.random() - 0.5 }));
19.session 与 cookie 的区别
session 保存在服务器,客户端不知道其中的信息;
cookie 保存在客户端,服务器能够知道其中的信息。
session 中保存的是对象,cookie 中保存的是字符串。
session 不能区分路径,同一个用户在访问一个网站期间,所有的 session 在任何一个地方都可以访问到。而 cookie 中如果设置了路径参数,那么同一个网站中不同路径下的 cookie 互相是访问不到的。
20.JavaScript 判断一个变量是对象还是数组 ?
在 JavaScript 中所有数据类型严格意义上都是对象,但实际使用中我们还是有类型之分,如果要判断一个变量是数组还是对象使用 typeof 搞不定,因为它全都返回 object。
第一,使用 typeof 加 length 属性
数组有 length 属性,object 没有,而 typeof 数组与对象都返回 object,所以我们可以这么判断
var getDataType = function(o){ if(typeof o == 'object'){ if( typeof o.length == 'number' ){ return 'Array'; } else { return 'Object'; } } else { return 'param is no object type'; } };
第二,使用 instanceof
利用 instanceof 判断数据类型是对象还是数组时应该优先判断 array,最后判断 object。
var getDataType = function(o){ if(o instanceof Array){ return 'Array' } else if ( o instanceof Object ){ return 'Object'; } else { return 'param is no object type'; } };
21.字符串翻转
var array1 = "hello word";
var array2 = [...array1].reverse().join("");
console.log(array2)
22.JS 是单线程,你了解其运行机制吗?
23.防抖、节流
<body> <div> <span>没有处理:</span> <input type="text" id="input_one"> <br> <span>防抖处理:</span> <input type="text" id="input_two"> <br> <span>节流处理:</span> <input type="text" id="input_three"> </div> </body>
function ajax(params) { console.log('ajax request:', params) } //防抖 function debounce(fn,delay) { var timeout; return function(args){ clearTimeout(timeout); timeout = setTimeout(() => { fn(args) },delay) } } //节流 function throttle(fn,delay){ var timeout,last; return function(args){ var now = new Date().getTime(); if(last&&now - last<delay){ clearTimeout(timeout); timeout = setTimeout(() => { last = now; fn(args) },(last+delay-now)) }else{ last = now; fn(args) } }; } let input_one = document.getElementById('input_one') input_one.addEventListener('keyup', function (e) { ajax(e.target.value) }) let debounceAjax = debounce(ajax,500); let input_two = document.getElementById('input_two') input_two.addEventListener('keyup', function (e) { debounceAjax(e.target.value) }) let throttleAjax = throttle(ajax,1000); let input_three = document.getElementById('input_three') input_three.addEventListener('keyup', function (e) { throttleAjax(e.target.value) })
0 条评论