边边角角,偶尔遇到——javascript

目录

边边角角的知识

1. in

数组

// 数组
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees        // 返回true
3 in trees        // 返回true
6 in trees        // 返回false

// -------------------------attention----------------------
"bay" in trees    // 返回false (必须使用索引号,而不是数组元素的值)
// -------------------------attention----------------------

"length" in trees // 返回true (length是一个数组属性)

delete和undefined

var mycar = {make: "Honda", model: "Accord", year: 1998};
delete mycar.make;
"make" in mycar;  // 返回false
var mycar = {make: "Honda", model: "Accord", year: 1998};
mycar.make = undefined;
"make" in mycar;  // 返回true

2. slice

可以不指定任何参数,返回原数组

splice、slice、substr、substring

3. isFinite

不太懂为什么???????

isFinite("0");       // true
Number.isFinite("0");       // false

4. 复制数组

// good
const itemsCopy = [...items];

5. 将类似数组的对象转为数组–Array.from

const foo = document.querySelectorAll('.foo');
const nodes = Array.from(foo);

6. URL

percent code

编码原因: Url中有些字符会引起歧义
编码格式:ASCII码
编码方式: %加上两位十六进制字符

encodeURI作对完整的URI进行编码,encodeURIComponent对URI的一个组件进行编码,所以encodeURI的安全字符更多,编码范围小。

url的三个js编码函数escape(),encodeURI(),encodeURIComponent()简介
网络标准RFC 1738做了硬性规定:

“只有字母和数字[0-9a-zA-Z]、一些特殊符号“$-_.+!*’(),”[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。”

  • escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值。比如"春节"的返回结果是%u6625%u8282,escape()不对"+"编码网页在提交表单的时候,如果有空格,则会被转化为+字符。服务器处理数据的时候,会把+号处理成空格。),主要用于汉字编码,现在已经不提倡使用。

  • encodeURI()是Javascript中真正用来对URL编码的函数。 编码整个url地址(编码后,它输出符号的utf-8形式,并且在每个字节前加上%),但对特殊含义的符号"; / ? : @ & = + $ , #"以及单引号,不进行编码。对应的解码函数是:decodeURI()。

  • encodeURIComponent() 能编码"; / ? : @ & = + $ , #"这些特殊字符。对应的解码函数是decodeURIComponent()。

7. a标签的download属性采坑

file方式打开无效,而且链接是http协议的无效

8. 使用 download 属性保存画布为PNG格式

save canvas as image

9. ES6 import 循环引用

ES6新特性:使用export和import实现模块化

10. null、undefined、""、0

null == ""				// false
undefined == ""			// false
null == 0				// false
undefined == 0			// false
Number(null)			// 0
Number(undefined)		// NaN
"" == 0					// true

关于=====

绝大多数场合应该使用 === ,只有检测 null/undefined 的时候可以使用 x == null ,因为通常我们不区分 null 和 undefined ,即将 x == null 作为 x === null || x === undefined 的缩写

11. chrome输入框autofill黄色背景

input:-webkit-autofill 导致chrome的输入框背景颜色变成黄色

  • <input type="text" autocomplete="off"> 并没有什么卵用
  • 还是乖乖用 box-shadow
input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
	-webkit-box-shadow: 0 0 0 1000px white inset;
}

12. setTimeout 0

How JavaScript Timers Work
setTimeout 的执行时间会大于(等待前一个函数执行完)等于设置时间,setInterval 则不一定,两次 interval 之间可能没有间隔,也可能某次被 drop 掉
Promise的队列与setTimeout的队列的有何关联?【优先级问题】

浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程

  1. javascript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行JS程序。
  2. GUI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
  3. 事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。(当线程中没有执行任何同步代码的前提下才会执行异步代码)

13. JS模块化

  • commonJS
// 暴露
module.exports = myModule;
// 引用s
var myModule = require('myModule');
  • AMD
define(['myModule'], function(myModule) {
  return something;
});
  • UMD
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
      // AMD
    define(['myModule', 'myOtherModule'], factory);
  } else if (typeof exports === 'object') {
      // CommonJS
    module.exports = factory(require('myModule'), require('myOtherModule'));
  } else {
    // Browser globals (Note: root is window)
    root.returnExports = factory(root.myModule, root.myOtherModule);
  }
}(this, function (myModule, myOtherModule) {
  // Methods
  function notHelloOrGoodbye(){}; // A private method
  function hello(){}; // A public method because it's returned (see below)
  function goodbye(){}; // A public method because it's returned (see below)

  // Exposed public methods
  return {
      hello: hello,
      goodbye: goodbye
  }
}));

14. 跨域cookie

15. 关于浏览器模式的那些事儿

从Chrome源码看浏览器如何构建DOM树

  • 怪异模式 会模拟IE,同时CSS解析会比较宽松,例如数字单位可以省略
  1. 怪异模式下的input和textarea的默认盒模型将会变成border-box:
    怪异模式下的input和textarea的默认盒模型将会变成border-box
  2. 标准模式下的文档高度是实际内容的高度:
    标准模式下的文档高度是实际内容的高度
    而在怪异模式下的文档高度是窗口可视域的高度:
    而在怪异模式下的文档高度是窗口可视域的高度
  • 有限怪异模式标准模式 的唯一区别在于在于对inline元素的行高处理不一样。
  1. 有限怪异模式下,div里面的图片下方不会留空白,如下图一所示;而在标准模式下div下方会留点空白,如下图二所示:
    不会留空白
    会留点空白
    这个空白是div的行高撑起来的,当把div的行高设置成0的时候,就没有下面的空白了。在怪异模和有限怪异模式下,为了计算行内子元素的最小高度,一个块级元素的行高必须被忽略。
  • 标准模式 将会让页面遵守文档规定

DOM树有一个最大的深度:maximumHTMLParserDOMTreeDepth,超过这个最大深度就会把它子元素当作父无素的同级节点,这个最大值是多少呢?512

16. input、change、propertychange区别

总结oninput、onchange与onpropertychange事件的用法和区别

  • change事件
    事件触发取决于表格元素的类型(type)和用户对标签的操作:

    • <input type="radio"><input type="checkbox"> 的默认选项被修改时(通过点击或者键盘事件)
      【IE(LTE8)中点击、失去焦点后才会触发,见 js change,propertychange,input事件小议】;
    • 当用户完成提交动作时 (例如:点击了 <select>中的一个选项,从 <input type="date">标签选择了一个日期,通过 <input type="file">标签上传了一个文件,等 );
    • 当标签的值被修改并且失焦后,但并未进行提交 (例如:对<textarea> 或者<input type="text">的值进行编辑后。).
  • input事件(IE9+):

    • 在value改变时实时触发,js改变value时不会触发;
    • <select> 不会触发
    • 通过addEventListener()注册
  • propertychange 事件

    • 当input设置为disable=true后,propertychange不会触发。
  • input 和 propertychange在 IE9 中都有个小BUG:通过右键菜单菜单中的 剪切删除 命令删除内容的时候不会触发

17. 从Chrome源码看浏览器的事件机制

  • 事件回收:

删掉一个DOM结点,不需要手动去释放它的事件,但是DOM结点一旦存在一个引用,即使你把它remove掉了,GC也不会去回收,如下:

<script>
    var p = document.getElementById("text");
    p.remove();
    window.gc();
</script>

执行了window.gc之后并不会去回收p的内存空间以及它的事件。因为还存在一个p的变量指向它,而如果将p置为null,如下:

<script>
    var p = document.getElementById("text");
    p.remove();
    p = null;
    window.gc();
</script>

最后的GC就管用了,或者p离开了作用域:

<script>
!function(){
    var p = document.getElementById("text");
    p.remove();
}()
window.gc();
</script>

自动销毁,p结点没有人引用了,能够自动GC回收。

18. __proto__prototype 的爱恨情仇

19. $.attr()$.prop()

jQuery函数attr()和prop()的区别

  • attr
    • DOM元素所对应的文档节点上的属性(attribute)
    • 设置的属性值只能是字符串类型
    • attribute的checked、selected、disabled就是表示该属性初始状态的值
  • prop对应着js对象
    • DOM元素(指的是JS对象,Element类型)上的属性(property)
    • 设置的属性值可谓为任意类型
    • property的checked、selected、disabled才表示该属性实时状态的值(值为true或false)

20. 判断自然数(>=0整数)

if (!n || typeof n !== 'number' || !isFinite(n) || n < 0 || Math.floor(n) !== Math.ceil(n)) {
	console.warn(`argument n: ${n} is not a natural number`);
}

Object.prototype.toString.call(NaN) => '[object Number]'

21. 数组最大/小值

Math.min.apply(null, array)
Math.max.apply(null, array)

【数组中不能有无法转化为数字的元素,否则会返回NaN】

Math.max.apply(null, [3,2,5,7,,3,,,9,7,87,78]) => NaN

22. jquery事件绑定

console.time('jq');
for(let i = 0; i < 10000; i++){
	$('.food_pic').on('click', function () {
		console.log(33333)
	});
}
console.timeEnd('jq');
console.time('js');
for(let i = 0; i < 10000; i++){
	$('.food_pic')[0].addEventListener('click', function () {
		console.log(4444444)
	});
}
console.timeEnd('js');
=============================>
// jq: 109.872ms
// js: 260.357ms
// 10000次 33333
// 10000次 4444444
var i;
function test1() {console.log(11111111)};
function test2() {console.log(22222222)};
console.time('jq');
for (i = 0; i < 10000; i += 1) $(document.querySelector('.food_pic')).on('click', test);
console.timeEnd('jq');
console.time('js');
for (i = 0; i < 10000; i += 1) document.querySelector('.food_pic').addEventListener('click', test);
console.timeEnd('js');
=============================>
// jq: 152.260ms
// js: 49.812ms
// 10000次 11111111
// 22222222

23. form nest

<form>不能嵌套,<ng-form>可以

24. exports、module.exports

module.exports 初始值为一个空对象 {}
exports 是指向的 module.exports 的引用
require() 返回的是 module.exports 而不是 exports

避免module.exports 指向新的对象时,exports 断开了与 module.exports 的引用

exports = module.exports = somethings
// 等价于:
module.exports = somethings
exports = module.exports

25. for 中的 let

怎么理解for循环中用let声明的迭代变量每次是新的变量?

for (let x…)的循环在每次迭代时都为x创建新的绑定

for (let i = 0; i < 3; i++) {
    setTimeout(() => {console.log("in for block", i)}, 1000);
}
// in for block 0
// in for block 1
// in for block 2

for 的 {}是 for () 的子作用域

for (let i = 0 /* 作用域a */; i < 3; console.log("in for expression", i), i++) {
    let i; //这里没有报错,就意味着这里跟作用域a不同,换做k可能更好理解
    console.log("in for block", i);
}
// in for block undefined
// in for expression 0
// in for block undefined
// in for expression 1
// in for block undefined
// in for expression 2

26. HTTP 协议

HTTP 协议入门

HTTP 1.1 管道机制:同一个TCP连接里,允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求
HTTP 1.0 Content-length: 用于区分数据包属于哪一个回应【因为管道机制可以一个TCP传多个回应】
HTTP 1.1 分块传输编码 Transfer-Encoding: chunked: 每个非空的数据块前有一个16进制的数值,表示这个块的长度。最后是一个大小为0的块,就表示本次回应的数据发送完了。

  • POST Content-Type
    • application/x-www-form-urlencoded(默认): 数据被编码成以 ‘&’ 分隔的键-值对, 同时以 ‘=’ 分隔键和值. 非字母或数字的字符会被 percent encoded: 这也就是为什么这种类型不支持二进制数据的原因 (应使用 application/form-data 代替).
    • application/form-data
    • text/plain
  • HTTP cookies 详解

27. 36个代码块,带你读懂异常处理的优雅演进

阶段备注
回调同步、异步
Promiseresolve:then 的第一个回调会立即插入 microtask 队列,异步立即执行
reject:那么 then 的第二个回调会立即插入 microtask 队列
抛出的异常和未捕获的 reject 会传到末尾,通过 catch 接住
resolve 决议会被自动展开(reject 不会)
链式流,then 会返回一个新的 Promise,其状态取决于 then 的返回值
macrotask 中 throw 的 error 无法捕获【指setTimeout等】(reject 可以)、microtask 可以
Async Awaitasync await 是 generator 的语法糖
await 不会自动捕获异常,但是会自动中断函数
try catch 进行异常捕获
macrotask 中 throw 的 error 无法捕获【指setTimeout等】(reject 可以)、microtask 可以
Decorator 统一异常捕获异常冒泡
兜底Node.js:监听全局错误 uncaughtException、unhandleRejection
浏览器:监听 window 全局错误 unhandlerejection、onrejectionhandled

28.JavaScript 运行机制详解:再谈Event Loop

  • setTimeout 在**"任务队列"的尾部**添加一个事件,因此要等到同步任务和"任务队列"现有的事件都处理完,才会得到执行。
  • HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔),不得低于4毫秒,如果低于这个值,就会自动增加。
  • node process.nextTick方法可以在当前"执行栈"的尾部----下一次Event Loop(主线程读取"任务队列")之前----触发回调函数。
  • node setImmediate 下次"Event Loop"触发,其和 setTimeout(fn,0) 执行顺序不确定

29. ES7 Decorator 装饰者模式

  • 适配器模式我们使用的场景比较多,比如连接不同数据库的情况,你需要包装现有的模块接口,从而使之适配数据库 —— 好比你手机使用转接口来适配插座那样;
  • 装饰模式不一样,仅仅包装现有的模块,使之 “更加华丽” ,并不会影响原有接口的功能 —— 好比你给手机添加一个外壳罢了,并不影响手机原有的通话、充电等功能;

30. JSON.parse(string) => Number 可能会溢出

31. post上传文件Content-type

需删除content-type,这样才会正确的结束boundary

32. module.exports 和 export default 不能混用

问题在于export default会利用babel编译

(function(module, exports) {
	exports.A= 674;
}),
(function(module, __webpack_exports__, __webpack_require__) {
	"use strict";
	Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
	/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "B", function() { return B; });
	
	exports.A= 674;
	var B= 1;
}),

33. viewport to read

34. window.performance

Navigation Timing

这里写图片描述

35. 如何使得a === 1 && a === 2 && a === 3

var val = 0
Object.defineProperty(window, 'a', {
  get: () => ++val
})
a === 1 && a === 2 && a === 3 && console.log('perfect?')

36. Proxy

handler

如何使得console.log('c' in p, p.c); // false, 37?

let handler = {
    get: function(target, name){
        return name in target ? target[name] : 37;
    }
};

let p = new Proxy({}, handler);

37. concat

concat方法创建一个新的数组,原始数组和新数组都引用相同的对象

var num1 = [[1]];
var num2 = [2, [3]];

var nums = num1.concat(num2);

console.log(nums);
// results in [[1], 2, [3]]

// modify the first element of num1
num1[0].push(4);

console.log(nums);
// results in [[1, 4], 2, [3]]

38. 循环

  1. forEach 相当于 for (i = 0, len = test.length; i < len; i++),循环时无影响
  2. for in 以任意序迭代一个对象的可枚举属性,遍历过程中的修改在之后的遍历具有不确定性
    • 不保证是否一个被添加的属性在迭代过程中会被访问到
    • 不保证一个修改后的属性(除非是正在被访问的)会在修改前或者修改后被访问
    • 不保证一个被删除的属性将会在它被删除之前被访问
// 改变数组本身的循环测试
var test = [1]
for (i = 0; i < test.length; i++) {
    console.log('--------i', i)
    test.push(i + 1)
    if (i >= 5) {
        break
    }
}
// --------i 0
// --------i 1
// --------i 2
// --------i 3
// --------i 4
// --------i 5

var test = [1]
for (i of test) {
    console.log('--------i', i)
    test.push(i + 1)
    if (i >= 5) {
        break
    }
}

// --------i 1
// --------i 2
// --------i 3
// --------i 4
// --------i 5

var test = [1]
test.forEach(function(i) {
    console.log('--------i', i)
    test.push(i + 1)
    if (i >= 5) {
        return
    }
})
// --------i 1

38. decodeURIComponent % 报错

decodeURIComponent("%")  ----->Uncaught URIError: URI malformed
decodeURIComponent("%25")  ----->%

39. 正则[]

/^(https|http):$/全匹配http:或者https:
/^[https:|http:]$/实际匹配/^[htps:|]$/

40. var、let、const

Referer: 25

varlet、const
没有块级作用域有块级作用域

41. sort 参数顺序

var c = [3, 6, 2, 8]
c.sort(function(a, b) {console.log(a, b)}) // a为后面一个,b为前面一个
// 6 3
// 2 6
// 8 2

42. set、map、weakSet、weakMap

  • set
    • 类似数组,但是成员的值都是唯一的
    • 应用:
// 去重
[...new Set(array)]
Array.from(new Set(array))
[...new Set('ababbc')].join('') // "abc"
  • map

    • 类似于对象,但是“键”的范围不限于字符串
  • weakSet:

    • 成员只能是对象
    • 弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用
    • 不可遍历
    • 应用:
// 保证了Foo的实例方法,只能在Foo的实例上调用
const foos = new WeakSet()
class Foo {
  constructor() {
    foos.add(this)
  }
  method () {
    if (!foos.has(this)) {
      throw new TypeError('Foo.prototype.method 只能在Foo的实例上调用!');
    }
  }
}
  • weakMap
    • 只接受对象作为键名(null除外)
    • 键名(非键值)所指向的对象,不计入垃圾回收机制
    • 不可遍历、无法清空
    • 应用:DOM作为键值、部署私有属性

43. 包装对象 Boolean

var a = new Boolean(false);
var b = a && true;
console.log(b);    //true

困惑:

  • 如何在调用函数时控制流程(出错则不继续执行余下代码,实际类似于return透传)(例如函数需要上下文中的参数,但是希望不满足条件就不执行余下外围代码)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值