javascript进阶核心

1. 变量。javascript

     使用全局变量需注意:java

     1. 全局变量的泛滥使用会致使变量覆盖,出现意想不到的问题。jquery

     2. 破坏代码的可移植性。json

     3. 使用var避免全局变量。闭包

    预解析:var的散布问题模块化

    JavaScript中,你能够在函数的任何位置声明多个var语句,而且它们就好像是在函数顶部声明同样发挥做用,这种行为称为 hoisting(悬置/置顶解析/预解析)。函数

JavaScript有一个特性叫作隐式全局变量,无论一个变量有没有用过,JavaScript解释器反向遍历做用域链来查找整个变量的var声明,若是没有找到var,解释器则假定该变量是全局变量,若是该变量用于了赋值操做的话,以前若是不存在的话,解释器则会自动建立它。这就是函数内部变量不加var会被解释成全局变量的缘由。性能

var myname = 'global';

function show(){
    console.log(myname);
}

show();  // global


function show2(){
    console.log(myname);
    var myname = 'show2';
}

show2() // undefined


function show3(){
    console.log(myname);
    var myname = 'show2';
    console.log(myname);
}

show3() // undefined     show2

2. for循环。this

for(var i=0; i< myarr.length; i++){

   //
}

若是这是一个对象的话,每次都要去查找对象的属性,影响性能,咱们能够这样写:spa

var i, myarr = [];
for(i = myarr.length;i--;){

//
}

for in 遍历对象属性。若是继承了,会查找原型链,遍历到原型中的属性,这不是指望的

for(n in obj){

 if(obj.hasOwnProperty(i)){
     //
   }
}

3. 命名规范。

    方法名按照驼峰命名法命名,由new调用的构造方法,首字母大写,通常方法首字母小写。

    变量名统一用下划线隔开单词的命名法。封装的私有方法,用下划线开头。

4. js的module模式。

    基本特征:

  1. 模块化,可重用
  2. 封装了变量和function,和全局的namaspace不接触,松耦合
  3. 只暴露可用public的方法,其它私有方法所有隐藏。 
// 实现对象的公,私封装

var Man = function(){
    // 能够在这里定义全部的私有属性
    var name = '张三';
    
    return {
        //暴露公有的接口
        echo: function(){
           console.log(name);
        }
    }


}

var m1 = new Man()

m1.echo()

匿名函数的两种闭包方式

//第一种

(function(){}())

//第二种
(function(){})()

//习惯使用第一种

为闭包引入全局变量

(function($){
//可使用$访问jquery对象了

}(jQuery))

上面使用了全局变量,若是我想声明全局变量呢?

var blog = (function(){

    //声明一个my对象来存储定义的方法和属性,这个是闭包的局部变量,其实就是全局的blog对象

    var my = {}, _name = '博客';
    
    my.Name = _name;   //给全局blog添加属性和方法
    my.show = function(){
       console.log(this.Name);
    }
    
   return my;


}())


blog.Name  // 博客

若是我想前面若是定义了blog就继承(在原来的基础上扩展),若是没有就定义呢?

var blog = (function(my){
    my.Name = '博客';
    my.show = function(){


    }
    
    return my;

}(blog || {}))

又有问题了,我想重载blog方法呢?

//文件1.js
var blog = {
   show: function(){
      console.log(111);
    }

}; 

//文件2.js,重载blog
var blog = (function(my){

     var oldShow = my.show;
     
     my.show = function(){

          oldShow();
          console.log(222);
     }


}(blog))

建立子模块

blogModule.CommentSubModule = (function () {
    var my = {};
    // ...

    return my;
} ());

当即调用方法的典型使用:

//给每一个对象绑定一个方法,点击显示该对象的索引

var elems = document.getElementsByTagName('a');

for (var i = 0; i < elems.length; i++) {

    elems[i].addEventListener('click', function (e) {
        e.preventDefault();
        alert('I am link #' + i);
    }, 'false');

}

//结果,全部点击都显示 I am link 10

var a = document.getElementById('results').getElementsByTagName('a');

for (var i = 0; i < a.length; i++){

	a[i].addEventListener('click', (function(n){
	
		return function(){
			console.log(n);
		}
	
	}(i)), false)
}

5. prototype和__proto__。

prototype和__proto__

__proto__是对象的默认私有属性,经过__proto__属性来造成原型链,查找对象的属性。

prototype 是构造器的原型。

例如:

var person = {}; 

这是一个对象,因此是有__proto__属性的,就是object对象。而它是没有prototype属性的。

var Person = function(name){
    this.name = name;
}

这是一个构造器,是有prototype属性的

Person.prototype.say = function(){
    console.log(this.name);
}

他们有什么联系呢?

var person = new Person('张三');

person是对象,全部应该有__proto__

实际上 person.__proto__ === Person.prototype === Object

接下来讲说继承。

直接用对象实现继承

var student = {
    __proto__: new Person('张三同窗')
}

student.say();   //张三同窗

用构造器来继承:

var Student = function(){}

Student.prototype = new Person('张三同窗');

var student = new Student();

student.say();  //张三同窗

6. 闭包。.

闭包是代码块(bar函数)和建立该代码块的上下文中数据(foo函数的做用域)的结合。

函数是“第一类”对象。这个名词意味着函数能够做为参数被传递给其余函数使用 ,接收该函数参数的函数就称为高阶函数。

function foo() {
  var x = 10;
  return function bar() {
    console.log(x);
  };
}
 
// "foo"返回的也是一个function
// 而且这个返回的function能够随意使用内部的变量x
 
var returnedFunction = foo();
 
// 全局变量 "x"
var x = 20;
 
// 支持返回的function
returnedFunction(); // 结果是10而不是20

这种形式的做用域称为静态做用域。

共享静态做用域

function baz() {
  var x = 1;
  return {
    foo: function foo() { return ++x; },
    bar: function bar() { return --x; }
  };
}
 
var closures = baz();
 
console.log(
  closures.foo(), // 2
  closures.bar()  // 1
);

7. 标准的JSON格式。

以前一直觉得JSON也是对象,如今才发现是一种错误的理解,json其实就是字符串的一种格式。

// 这是JSON字符串
var foo = '{ "prop": "val" }';
 
// 这是对象字面量
var bar = { "prop": "val" };

var obj = JSON.parse(foo);

console.log(obj.prop)

var str = JSON.stringify(bar);

console.log(str); // { "prop": "val" }

JSON有很是严格的语法,冒号两边的数据必须都有引号,而且必须是双引号,单引号就不行。

8. javascript的DOM

(非IE,ie的event也属于window)

Event事件。

//ie 和 非ie
function show(e){
   e = e || window.event;
   e.preventDefault();  // 阻止默认行为
   e.stopPropagation();  // 阻止事件冒泡
}
相关文章
相关标签/搜索