顾名思义js笔记喽
所有记录再此的都为已经理解的内容。


1.常见的浏览器内核

  1. Trident 内核:IE, 360,搜狗浏览器 MaxThon、TT、The World,等。[又称 MSHTML]
  2. Gecko 内核:火狐,FF,MozillaSuite / SeaMonkey 等
  3. Presto 内核:Opera7 及以上。[Opera 内核原为:Presto,现为:Blink]
  4. 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)
})

24.跨域处理

参考链接


25.常见web攻击

参考链接

参考资料

  1. MDN
  2. w3cshool
  3. 知乎