Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

javascript #9

Open
MikeMiller3 opened this issue Sep 5, 2017 · 0 comments
Open

javascript #9

MikeMiller3 opened this issue Sep 5, 2017 · 0 comments

Comments

@MikeMiller3
Copy link
Owner

MikeMiller3 commented Sep 5, 2017

var let & const

var和声明的变量会被‘提升’hoist到作用域的最前面(function声明的函数也会被提升,函数表达式不会)
let的提升https://www.jianshu.com/p/b87d620185f2

console.log(a);//Uncaught ReferenceError: a is not defined,变量未声明
console.log(a);//undefined,变量声明提升
var a = 1

相当于

var a;//提升到最前面
console.log(a);//undefined
a = 1

let和const声明的变量会绑定当前代码块(大括号包裹的部分),不可重复声明

console.log(b);//b is not defined
let b = 1
let b = 2;//Identifier 'b' has already been declared
if(true){
let a = 1
}
console.log(a);//a is not defined

var和let对外部作用域的影响

a = 1;
(function() {
console.log(a);//undefined
var a = 2
}) ()
a = 1;
(function() {
console.log(a);//Uncaught ReferenceError: a is not defined
let a = 2
}) ()

ES6规定,var和function声明的全局变量,属于全局对象的属性;let命令、const命令、class命令声明的全局变量,不属于全局对象的属性
var a = 1;
let b = 2;
console.log(window.a);//1
console.log(window.b);//undefined

类型

基本类型Undefined Null Boolean Number String Symbol
引用类型Object

类型的隐式转换

使用 == 号比较

  • 数组会转为字符串
  • 布尔值会转为数字
  • 两个对象会比较引用
  • 两边一个字符串一个数字,字符串会转数字
    比如:
    0 == false; //0 == 0
    0 == ''; // 0==0
    [] == false; // '' == 0 即0 == 0
    [] == ![]; //[] == false即'' == 0即0 == 0

typeof & instanceof

http://bonsaiden.github.io/JavaScript-Garden/#types.instanceof
http://bonsaiden.github.io/JavaScript-Garden/#types.typeof
因js的设计缺陷,只用于比较自定义对象,否则请使用Object.prototype.toString()方法:

function is(type, obj) {
    var clas = Object.prototype.toString.call(obj).slice(8, -1);
    return obj !== undefined && obj !== null && clas === type;
}

shim和polyfill

shim: 使用已经存在的API创建一个新的API
polyfill: 是浏览器API的shim。通常先判断一个API是否存在,如果不存在就实现一个,实现的这段代码就是polyfill

伪数组

  • 伪数组是个对象,有length属性,属性名为0,1,2...
  • arguments,jQuery对象,document.getElementsByTagName返回值都是伪数组
  • 转数组:通过Array.from()或Array.prototype.slice.call()

数组去重

  • [...new Set(arr)]
  • @ref

数组常用算法

  • 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
  • 如何判断一个数组中的元素是否完全在另一个数组中?

arguments

arguments对象是个伪数组,除了length属性外不能使用数组的slice等方法
可以转换为数组:
var arg = Array.prototype.slice.call(arguments)
var arg = [].slice.call(arguments)
var arg = Array.from(arguments)
var arg = = [...arguments]
强烈建议不要使用 arguments.callee 和它的属性,已经在严格模式中废除

call、apply、bind

  • call和apply
    call和apply都是为了动态改变this出现的,一个对象没有某个方法而另一个对象有时,可以借助这两个方法来调用。
    call接收固定参数,按顺序传递;apply接收不定参数,传递数组(如arguments)
//获取数组中最大值
//Math.max参数个数不限
var arr = [1,3,2]
Math.max.apply(null, arr);//3
Math.max(...arr)

//判断类型
var clas = Object.prototype.toString.call(obj).slice(8, -1);
  • bind 同样改变this指向,但不立即执行
    fun.bind(thisArg[,arg1[,arg2...]])
    绑定函数的this指向和预设参数(作为第二个参数)
//1
function exportList(businessType){
                that.$http.post("/common/export",{}).then(function(res){
                    this.$message.success({message: this.res.data})
                }.bind(this))
//因为函数会改变this指向,所以函数内部的this通过bind方法会有问题,可通过bind解决(常用)

//2 mdn是个好东西

this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 返回 81

var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域

// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81

当使用 for in 循环遍历对象的属性时,原型链上的所有属性都将被访问

注意: for in 循环不会遍历那些 enumerable 设置为 false 的属性;比如数组的 length 属性
如果一个属性在原型链的上端,则对于查找时间将带来不利影响。特别的,试图获取一个不存在的属性将会遍历整个原型链。
提防原型链过长带来的性能问题,并知道如何通过缩短原型链来提高性能。 更进一步,绝对不要扩展内置类型的原型,除非是为了和新的 JavaScript 引擎兼容
hasOwnProperty 是 JavaScript 中唯一一个处理属性但是不查找原型链的函数。
使用 for in 遍历对象时,推荐总是使用 hasOwnProperty 方法, 这将会避免原型对象扩展带来的干扰,不要对代码运行的环境做任何假设,不要假设原生对象是否已经被扩展

function A(){
this.a = 1;
}
function B(){
this.b = 2
}
B.prototype = new A()
B.prototype.constructor = B
var b = new B()
for(var i in b){
//if(b.hasOwnProperty(i)){//使用hasOwnProperty解决这个问题
console.log(`${i}:${b[i]}`)
//}
}
/*console
b:2
a:1
constructor:function B(){
this.b = 2
}
*/

创建自定义对象的几种方式

工厂模式
构造函数模式
原型模式
组合构造函数和原型模式
动态原型模式
寄生构造函数模式
稳妥构造函数模式

对一个函数使用new操作符之后发生了什么

 function Animal(name){
this.name = name
};
new Animal('Cat');

1.创建了一个对象,它继承自Animal.prototype
2.执行构造函数Animal,this指向创建的对象
3.返回创建的对象。特别的,如果构造函数中显式地return了一个对象,则返回这个对象。
var object = {};
object.prototype = Animal.prototype;
Animal('Cat');
return object;

深拷贝和浅拷贝

@see

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant