JavaScript之类数组对象与arguments
类数组对象类数组对象:拥有一个length属性和若干索引属性的对象
举个例子:
12345678var array = ['name', 'age', 'sex'];var arrayLike = { 0: 'name', 1: 'age', 2: 'sex', length: 3}
为什么叫类数组对象呢?
我们从读写、获取长度、遍历三个方面看看这两个对象。
读写12345console.log(array[0]); //nameconsole.log(arrayLike[0]); //namearray[0] = 'new name';arrayLike[0] = 'new name';
长度12console.log(array.length); // 3console.log(arrayLike.length); // 3
遍历123456for(var i = 0, ...
JavaScipt高级(四) 闭包
定义MDN 对闭包的定义为:
闭包是指那些能够访问自由变量的函数。
那什么 是自由变量呢?
自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。
由此,我们可以看出闭包共有两部分组成:
闭包 = 函数 + 函数能够访问的自由变量
举个例子:
1234567var a = 1;function foo() { console.log(a);}foo();
foo函数可以访问变量a,但是a既不是foo函数的局部变量,也不是foo函数的参数,所以a就是自由变量。
那么,函数foo+foo函数访问的自由变量a不就是构成了一个闭包嘛。
还真是这样的!
引用《JavaScript 权威指南》中就讲到:从技术的角度讲,所有的 JavaScript 函数都是闭包。
上述只是介绍的理论上的闭包,还有一个实践角度上的闭包,Tom 大叔翻译的关于闭包的文章中的定义:
ECMAScript 中,闭包指的是:
从理论角度:所有的函数。因为它们都在创建的时候就将上层上下文的数据保存起来了。哪怕是简单的全局变量也是如此,因为函数中访问全局变量就 ...
JavaScript高级(三) 作用域
前言当JavaScript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)。
变量对象(Variable object,VO)
作用域链(Scope chain)
this
变量或函数的上下文决定了它们可以访问哪些数据,以及它们的行为。每个上下文都有一个关联的变量对象(variable object),而这个上下文中定义的所有变量和函数都存在于这个对象上
作用域链当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。
下面,让我们以一个函数的创建和激活两个时期来学习作用域链是如何创建和变化的。
函数创建函数的作用域在函数定义的时候就决定了。
这是因为函数有一个内部属性[[scope]],当函数创建时,就会保存所有父变量对象到其中,你可以理解[[scope]]就是所有父变量对象的层级链,但是注意:[[scope]]并不代表完整的作用域链。
举个 ...
时间空间复杂度
什么是时间复杂度时间复杂度是一个函数,它定性描述该算法的运行时间,在软件开发中,时间复杂度就是用来方便开发者估算出程序运行时间,通常用算法的操作单元数量来代表程序消耗的时间,这里默认CPU的每个单元运行消耗的时间都是相同的。假设算法的问题规模为n,那么操作单元数量便用函数f(n)来表示,随着数据规模n的增大,算法执行时间的增长率和f(n)的增长率呈现一定的关系,这称作为算法的渐近时间复杂度,简称时间复杂度,记为 O(f(n)),其中n指的是指令集的数目。
什么是大O大O用来表示算法执行时间的上界,也可以理解为最差情况下运行的时间,数据量和顺序等情况对算法的执行时间有非常大的影响,这里假设的是某个输入数据用该算法运行的时间,比其他数据的运算时间都要长。
插入排序的时间复杂度我们都说是O(n^2) ,但是插入排序的时间复杂度和输入数据有很大的关系,假如输入数据是完全有序的,则插入排序的时间复杂度是O(n),假如输入的数据是完全倒序的,则时间复杂度是O(n^2),所以最坏是O(n^2) 的时间复杂度,我们说插入排序的时间复杂度为O(n^2)。
快速排序是O(nlogn),快速排序的在最差的情 ...
如何刷leetcode
写在前面本文主要是给博主记录一个刷leetcode的方法,主要是参考大佬[全栈潇晨](搞定大厂算法面试之leetcode精讲 (xiaochen1024.com))的方式来进行学习,放在博客上方便参考,也希望能够帮助到每一个热爱前端的老铁。
如何刷题切碎知识点对每个类型的题目形成一套解题思路和模板,比如解动态规划的步骤有:
根据重叠子问题定义状态
寻找最优子结构推导状态转移方程
确定dp初始状态
确定输出值
刻意练习要练习缺陷的、弱的地方,那些写起来不舒服、不爽、枯燥的题目就是薄弱点,不要只练习熟悉类型的题
反馈在leetcode上寻找别人的解题思路,包括评论区的讨论,还有程序的运行时间和占用内存的数据,顺便提一句,leetcode的运行时间和占用内存情况的数据不准确,就当个参考就好,不要太在意运行时间的排名。
多写反复练习,加强记忆,三分学,七分练。
总结规律将刷题的套路总结成自己方法,比如拆解问题、找基本的子问题、问题的组装、数学归纳等等。最后这些方法落实到代码层面无非是if else,for while、递归等,总结了这些规律,才能在题目变化的时候还能找到正确的解题路径。题目 ...
JavaScript高级(二) 继承
1. 原型链继承123456789101112131415function Parent(){ this.name = '缪克立';}Parent.prototype.getName = function(){ return this.name}function Child(){}Child.prototype = new Parent();var child1 = new Child();console.log(child1.getName()) // 缪克立
问题:
引用类型的属性被所有实例共享,举个例子:
123456789101112131415161718192021222324252627function Parent(){ this.names = ['缪克立', '缪立克'];}function Child(){ this.age = [18]}Child.prototype = n ...
JavaScript高级(一) 原型到原型链
构造函数创建对象先使用构造函数创建一个对象
123456function Person(){} // 函数对象,函数也是对象var person = new Person();person.name = 'Kevin';console.log(person.name) // Kevin
这个例子,Person就是一个构造函数,跟Java语言差不多,我们也可以使用new创建一个实例对象person
进入正题:
prototype每个函数都有一个属于自己的 prototype 属性,就是我们经常在各种例子中看到的那个 prototype ,比如:
12345678910function Person(){}// 虽然写在注释里,但是你要注意:// prototype是函数才会有的属性Person.prototype.name = 'Kevin';var person1 = new Person();var person2 = new Person();console.log(person1.name) // ...