javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript 引用类型

JavaScript 引用类型实例详解【数组、对象、严格模式等】

作者:alogy

这篇文章主要介绍了JavaScript 引用类型,结合实例形式详细分析了JavaScript 数组、对象、严格模式引用类型相关概念、原理及操作注意事项,需要的朋友可以参考下

本文实例讲述了JavaScript 引用类型。分享给大家供大家参考,具体如下:

数组

在ECMAScript中数组是非常常用的引用类型
ECMAScript所定义的数组和其他语言中的数组有着很大的区别
数组也是一种对象

创建数组

//方法一
var arr = new Array();

//方法二
var arr1 = [];

特点

常用方法

push、pop
shift、unshift
splice、slice
concat、join、sort、reverse(逆序)

影响原数组
splice()
arr.splice(开始项,[控制几位数,值]); //statr ,count ,
var arr = [1,2,3,4,5,6,7];
var zf = arr.splice(3); //控制几位数, 默认值 :arr.length-1 //包括3 原来项数
console.log( arr ); //[1,2,3]
console.log( zf ); //[4,5,6,7] //返回值 -- 取出的内容

var arr = [1,2,3,4,5,6,7]; 
var zf = arr.splice(3,2); //截取
console.log( arr ); //[1, 2, 3, 6, 7]
console.log( zf ); //[4,5] 

var arr = [1,2,3,4,5,6,7]; 
var t = arr.splice(3,2,'zf','dd'); //替换
console.log( arr ); //[1,2,'zf','dd',6,7]
console.log( t ); //[4,5]

var arr = [1,2,3,4,5,6,7]; 
var t = arr.splice(3,0,'zf','dd'); //插入
console.log(arr); //[1,2,3,'zf','dd',4,5,6,7]
console.log( t ); //[] //如果为0 ,去除空数组

var arr = [1,2,3,4,5,6,7]; 
var 12 = arr.splice(-4); //截取
console.log( arr ); //[1,2,3]
console.log( zf ); //[4,5,6,7]

//
slice(stat,end) //去出了end-stat 项。 不包括end项。

var zf = arr.sort(function ( a,b ) { //传递匿名函数,通过匿名函数参数判断大小。
  if( a>b ){
    return 1;
  } else if( a<b ){
    return -1;
  } else {
    return 0;
  }
});
console.log( arr ); //["a", "b", "e", "z"]
console.log( zf ); //["a", "b", "e", "z"]

// 影响原数组
push , pop ,unshift ,shift ,splice ,reverse ,sort
// 未影响 原数组
concat ,slice ,join

ES5数组新特性

位置方法:indexOf lastIndexOf
迭代方法:every filter forEach some map
缩小方法:reduce reduceRight

// indexOf(); //查找位置 

var arr = [234,23,45,46,45,645,56];

//1个参数的时候,表示传值 返回索引位置
var idxVal = arr.indexOf(45);

//2个参数的时候, 第一个表示查询的值,第二个参数是 传值,表示起始开始查询的起始位置
var idxVal = arr.indexOf(2,3);

//查找数组比较的时候 是 "===" 

//找不到返回 -1

//迭代方法

//every : 对于数组每一个元素进行一个函数的运行 如果函数都返回true, 最后则返回true。 如果有一个返回false 最后结果则返回false。
// 测试数组的所有元素是否都通过了指定函数的测试 

var arr = [1,2,3,4,3,2,4,6];

var reslut = arr.every(function ( item,index,array ) {
  
  return item > 0;
  
});

console.log( reslut ); //true

//filter : 对于数组的每一个元素进行一个函数的运行 给定的函数执行, 把过滤后的结果返回。

var arr = [1,2,3,4,3,2,4,6];

var reslut = arr.filter(function ( item,index,array ) {
  
  return item > 2; //所有大于2 的过滤出来
  
})

console.log( reslut ); //[3, 4, 3, 4, 6]

//forEach : 循环数组每一项, 并执行一个方法
// 方法中的参数:数组成员的值,数组成员的索引,原数组(修改原数组会影响原来遍历的数组)

var arr = [1,2,3,4,3,2,4,6];

arr.forEach(function ( item,index,array ) {
  
  console.log( item );
  
});

var arr1 = ['tan', 'cyan', 'pink', 'red'];
arr1.forEach(function ( val, idx, arrs ) {
  
  return 1; // 返回返回并不会影响原数组
  
});
console.log(arr);

//map : 对于数组的每一个元素进行一个函数的运行 可以经过函数执行完毕  把新的结果返回, 原数组不变。

var arr = [1,2,3,4,3,2,4,6];

var reslut = arr.map(function ( item,index,array ) {
  
  return item * 3;
  
}); 

console.log( reslut ); //[3, 6, 9, 12, 9, 6, 12, 18]

//some : 对于数组每一个元素进行一个函数的运行 如果有一项返回true 最后则返回true 如果每一项都返回false, 最后才返回false。 

var arr = [1,2,3,4,3,2,4,6];

var reslut = arr.some(function ( item,index,array ) {
  
  return item > 5; //有一个返回true, 就返回true
  
});

console.log( reslut ); //true


//模拟filter方法
Array.prototype.filter = function ( cb ) {
  
  var reslut = [];
  
  try{
    
    if ( cb && cb.constructor === Function ) {
        
      for ( var i=0; i<this.length; i++ ) {
        
        if ( cb.call(this[i],this[i],i,this) ) {
          
          reslut.push(this[i]);
          
        }
    
      }
      
    }
    
  }catch(e){
    //TODO handle the exception
  }
  
  return reslut ? reslut : '';
  
}

var a = arr.filter(function ( item,index,arr ) {
  
  return item > 2;
  
});
console.log( a );

// 模拟some
Array.prototype.some = function ( fn ) {
  
  try{
    
    if ( fn && fn.constructor === Function ) {
      
      
      for ( var i=0; i<this.length; i++ ) {
        
        // 存在一个函数执行结果 为true , 返回true
        if ( fn.call(this[i], this[i], i, this) ) {
          
          return true;
          
        }
        
      }
      return false;
    }
    
  }catch(e){
    //TODO handle the exception
  }
  
}

var arr = [1,2,3,4,3,2,4,6];

// reduce reduceRight

// 前一个值, 当前值, 索引位置, array 
// 数组中的每个值(从左到右)开始合并,最终为一个值。
// 接收一个函数作为累加器,数组中的每一个值(从左到右)开始合并,最终为一个值。
var reslut = arr.reduce(function ( prev,cur,index,array ) {
  
  return prev + cur;
  
});

console.log( reslut ); //25

// reduceRight 从右开始遍历
var reslut1 = arr.reduceRight(function ( prev,cur,index,array ) {
  
  return prev + cur;
  
});

console.log( reslut ); //25


// 得到接口的对象

var o = (function() {
  var person = {
    name: 'xixi',
    age: 22,
  }
  return {
    sayName: function(k) {
      return person[k];
    },
  }
}());

var person = ['name', 'age'].reduce(function (obj, k) {
//   console.log(obj, k,'--');
  obj[k] = o.sayName(k);
  return obj;
},{});

console.log(person);

数组判断方法:
Array.isArray();
判断是否为数组,如果是,则返回true,否则返回false。

var arr = [];
console.log( Array.isArray(arr) );

填充方法:
fill();
实现对数组的填充
参数:接受值,直接填充,如果是函数,也是直接填充

// arr.fill(1);
// arr.fill(function () {
//   return 2;
// });
// arr.fill([1,2,3]);
arr.fill({x: 1});

console.log(arr);

Object

引用类型都是Object类型的实例,Object也是ECMAScript中使用最多的一种类型(就像java.lang.Object一样,Object类型是所有它的实例的基础) //所有类的 基础类。

Object类型的创建方式、使用

对于Object类型应用for in 枚举循环

Obj每个实例都具有属性和方法

Constructor: 保存着用于创建当前对象的函数。(构造函数)

hasOwnProperty(propertyName):用于检测给定的属性在当前对象实例中(而不是原型中)是否存在。

isPrototypeOf(Object): 用于检查传入的对象是否是另外一个对象的原型。

propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举。

toLocaleString():返回对象的字符串表示。该字符串与执行环境的地区对应.

toString():返回对象的字符串表示。

valueOf():返回对象的字符串、数值或布尔表示。

OBject.prototype.toString()

Object.prototype.toString
作用:根据内部的this返回一个类似于这样的字符串 [object constructorName]
这个方法有个缺点,不能获取用户自定义对象的具体类型.
只能获取内置对象的类型.
自定义对象类型都返回:[object Object]

console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call(Array)); // [object Fcuntion]
console.log(Object.prototype.toString.call(new Date())); // [object Date]

// 简写方式
console.log(({}).toString.call([])); // [object Array]

toString();

// 字符串 ==> String.prototype.toString();
var a = 't';
console.log(a.toString()); // t
var a = new String(); 
console.log(a.toString()); // 空字符串
var a = new String('string');
console.log(a.toString());  // string

// 数组 ==> Array.prototype.toString();
var b = [1, 2, 3, 4];
console.log(b.toString()); // 1,2,3,4
var b = [];
console.log(b.toString()); // 空字符串
var b = new Array();
console.log(b.toString()); // 空字符串
var b = new Array(3, 5);
console.log(b.toString()); // 3,5

// 对象 ==> Object.prototype.toString();
var c = {};
console.log(c.toString()); // [object Object]

// 函数
console.log(Function.toString()); // function Function() { [native code] }
console.log(Array.toString()); // function Array() { [native code] }
console.log(RegExp.toString()); // function RegExp() { [navtive code] }

关于JSON函数

JSON.parse()

作用:将JSON字符串解析成JavaScirpt值。在解析过程中,可以选择性的修改某些属性的原始解析值。
参数1:JSON字符串
参数2: reviver 函数,用来转换解析出的属性值。(可选参数)
返回值:解析出的一个 Object

console.log(JSON.parse(10)); // 10
console.log(JSON.parse(true)); // true
console.log(JSON.parse('"xixi"')); // xixi
console.log(JSON.parse(null)); // null
console.log(JSON.parse('"undefined"')); // undefined
console.log(JSON.parse("[]")); // []

如果指定了 reviver 函数,解析的出的Object, 解析值本身以及它所包含的所有属性,会按照一定的顺序(从最最里层的属性开始,一级级往外,最终到达顶层)分别去调用 指定的reviver 函数。

在调用过程中,当前属性所属的对象会作为this值,当前属性名和属性值会分别作为第一个参数和第二个参数传入 reviver 函数中,如果 reviver 函数返回undefeind,则当前属性会从属性对象中删除,如果返回了其它值,则返回的值会成为当前属性新的属性值。
当遍历到最顶层的值(解析值)时,传入reviver函数的参数会是空字符串''(因为此时已经没有真正的属性)和当前的解析值(有可能已经被修改过),当前的this值会是{"":修改过的解析值},

JSON.parse('{"p": 5}', function (key, val) {

 if(key === '') return val;   // 如果到了最顶层,则直接返回属性值
  
 return val * 2;
  
}); 

JSON.stringify();

stringify(value [,replacer, [space]]);
将任意的JavaScript值序列化成JSON字符
参数1:value: 将序列化成JSON字符串的值
参数2:replacer: 可选,如果是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理。 如果是一个数组,则暴行在这数组中的属性名才会被序列化到最终的JSON字符串中。
参数3:space, 指定缩进可通的空白字符串,用于美化输出。 控制结果字符串里的间距。

注意:

Object.create

ES5为对象提供了一个Object.create();
作用:创建一个类,是一种寄生式继承。
返回一个类,这个类的原型指向传递进来的对象。

创建的实例化对象,构造函数指向的是继承的对象的类的构造函数。本身没有原型,可以通过原型链找到继承的对象类中的原型。具有继承对象上的属性以及方法。
因此,创建的实例化对象可以使用继承对象上的属性和方法。

var Book = function (title, price) {
  
  this.title = title;
  
  this.price = price;
  
}

Book.prototype.sayTitle = function () {
  
  return this.price;
  
}

var book = new Book('one', 10);

// 创建一个继承类
var NewBook = Object.create(book);

console.log(NewBook.constructor);

var price = NewBook.sayTitle();

console.log(price);

// 模拟 Object.create();
// 寄生式继承
Object.prototype.create = function ( obj ) {
  
  try{
    
    if ( obj && obj.constructor === Object ) {
      
      function F () {}
      
      F.prototype = obj;
      
      return F;
      
    }
      
    
  }catch(e){
    //TODO handle the exception
  }
  
}

// 创建一个继承类
var NewBook = Object.create(book);

console.log(NewBook.constructor);

var price = NewBook.sayTitle();

console.log(price);

Object.defineProperty

Object.defineProperty();
直接在一个对象上定义一个新属性,或者修改一个已经存在的属性,并返回这个对象。
参数1:需要被设置的对象
参数2:设置的属性名
参数3:配置项,添加属性的特性属性

特性属性:
value:该属性值,默认值:undefeind
writable: 可否被修改,默认值:false (不能被修改)
configuarable: 能否通过delete删除属性从而重新定义属性,能够修改属性的特性,或者能否把属性修改为访问属性。 默认值:false;(不可以重新定义或删除)
enumerable: 是否可以被for-in枚举。默认值:false

var obj = {};

Object.defineProperty(obj, 'title', {
  
  value: 'tan',
//        writable: true,
  configurable: false,
//        enumerable: true
  
});

delete obj.title;

//      obj.title = 'pink';

//      for ( var i in obj ) {
//        
//        console.log(obj[i]);
//        
//      }

console.log(obj);

特性方法:
set:给属性提供setter的方法,如果没有setter则为undefined。默认值undefiend。
参数:该参数的新值分配给该属性。默认:undefined

Object.defineProperty(obj, 'title', {
  
  get: function () {
    console.log('get');
    return this._title;
  },
  set: function ( val ) {
    this._title = val;
  }
  
});

obj.title = 'pink';

var t = obj.title;

defineProperties

在一个对象上添加或修改一个或多个自有属性,并返回该对象。
参数1:表示要被处理的对象
参数2:定义多个属性特性对象

var obj = {}

Object.defineProperties(obj, {
  
  color: {
    value: 'tan'
  },
  
  names: {
    value: 'zf'
  }
  
});

console.log( obj );

getOwnPropertyNames

Object.getOwnPropertyNames();
返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性)组成的数组。
参数:需要获取的对象。

getOwnPropertyDescriptor

Object.getOwnPropertyDescriptor();
指定对象上一个自由属性对应的属性描述符。(自由属性指的直接赋予该对象的属性,不需要从原型链上进行查找的属性)
参数1: 获取的对象。
参数2:获取的属性值

模拟map

模拟java中的Map

    
//简单实现 map

function Map () {
  
  //priveate 的对象来保存 key 和 val
  var obj = {};
  
  // put 方法
  this.put = function ( key,val ) {
    
    
    obj[key] = val;  //把键值对 绑定到object上.
    
  }
  
  //获得map 容器的个数
  this.size = function () {
    
    var count = 0;
    
    for ( var i in obj ) {
      
      count++;
      
    }
    
    return count;
    
  }
  
  //根据key 得到 val
  this.get = function ( key ) {
    
    return obj[key] || (obj[key] === 0) || (obj[key] === false) ? obj[key] : null;
    
  }
  
  // remove 删除方法
  this.remove = function ( key ) {
    
    if ( obj[key] || obj[key] === 0 || obj[key] === false ) delete obj[key]; 
    
  }
  
  //eachMap 遍历 map 容器的方法
  this.eachMap = function ( cb ) {
    
    if ( cb && cb.constructor === Function ) {
      
      for ( var i in obj ) {
        
        cb.call(this,i,obj[i]);
        
      }
      
    }
    
  }
  
}

var m = new Map();

m.put('01',120);
m.put('02','tan');

//      console.log( m.size() );
//      
//      console.log( m.get('0') );

//      m.remove('01');
//      console.log( m.get('01'),'--' );

m.eachMap(function ( key,val ) {
  
  console.log( key,val,'---' );
  
});    

去掉数组的重复项

var arr = [1,2,4,2,3,4,5,546,57,6,5,4,31,57];

//js 对象特性, 数组去重 
// 在 js 对象 中 key 是永远 不会重复的.


// 1, 把数组转成一个js的对象
// 2,把数组中的值,变成js 对象当中的key
// 3,把对象再还原成数组

//数组转对象
var toObject = function ( arr ) {
  
  var reslutObj = {};
  
  for ( var i=0; i<arr.length; i++ ) {
    
    if ( arr ) {
    
      reslutObj[arr[i]] = null; //赋值为任意值
      
    }
    
  }
  
  return reslutObj;
  
}

//对象转成数组
var toArray = function ( obj ) {
  
  var reslutArr = [];
  
  for ( var attr in obj ) {
    
    if ( obj.hasOwnProperty(attr) ) { //判断是否是自身上面的属性
      
      reslutArr.push(attr);
      
    }
    
  }
  
  return reslutArr;
  
}

//去掉数组中的重复项
function uniq ( arr ) {
        
  return toArray(toObject(arr));
        
}
  
console.log( uniq(arr) );  

其他引用类型

单体对象(不需要实例化对象,就可以使用的方法):

Global对象(全局)这个对象不存在,无形的对象(特别的,特殊的存在)
其内部定义了一些方法和属性:encodeURI 、encodeURIComponent、decodeURI、decodeURIComponent、eval、parseInt、parseFloat、isNaN(在js 里面 只有NaN 自己不等于自己本身的)、Escape、 unescape

// encodeURI 、encodeURIComponent、

var uri = 'http://www.baidu.com cn';
var str1 = encodeURI(uri); //http://www.baidu.com%20cn         //(url: //不会进行编码)
var str2 = encodeURIComponent(uri); //http%3A%2F%2Fwww.baidu.com%20cn //任何不标准的文字都会进行编码

console.log( str1 );
console.log( str2 );

// decodeURI、decodeURIComponent、
console.log( decodeURI(str1) ); // http://www.baidu.com cn
console.log( decodeURIComponent(str2) ); // http://www.baidu.com cn

//eval(string) 方法 无形的javascript 解析器

var str1 = 'var a = 10; var b = 20;';
eval(str1);

console.log( a+b );

//数组字符串 直接使用: eval(strArr);

var arr = '[10,203,345,45,6]';

var evalArr = eval(arr);

console.log( evalArr );

//对象字符串 
var obj = '{name: "123", age: 20}';

var evalObj = eval('(' + obj + ')' );

console.log( evalObj );//Object {name: "123", age: 20}

//escape unescape URI 转码
var str = '八百米';
var str2 = escape(str); //%u516B%u767E%u7C73

console.log( str2 );

Math对象
内置的Math对象可以用来处理各种数学运算
可以直接调用的方法:Math.数学函数(参数)
求随机数方法:Math.random(),产生 [0,1) 范围一个任意数

Date对象
获取当前时间的一系列详细方法

var date = new Date();

console.log( date.getTime() );   //当前时间的毫秒数

基本包装类型:Boolean、String、Number

Function类型、RegExp类型

简单单体和闭包单体

单体(singleton)模式是js中最基本但又最有用的模式之一,它可能比其他任何模式都常用。
这种模式提供了一种将代码组织为一个逻辑单元的手段,这个逻辑单元中的代码可以通过单一的变量进行访问。通过确保单体对象只存在一份实例,就可以确信自己的所有代码使用的都是同样的全局资源。

简单单体

// 简单单体模式  (只能创建一个实例)//无法通过new 关键字来实例化.
var Singleton = { //当成模板类 
  attr1: true,
  attr2: 10,
  
  method1: function () {
    
    console.log( this.attr1 );
    
  }
  
}

Singleton.method1();

//划分命名空间(区分代码)
  

闭包单体

//  利用闭包来创建单体 , 闭包主要的目的 , 保护数据

var alogy = {};
alogy.singleton = (function () {
  
  
  //添加私有成员
  
  var a = 100;
  var fn1 = function () {
    
    console.log( a );              
    
  }
  
  // 块级作用域里的执行结果赋值 单体对象
  return {
    attr1: 10,
    attr2: 20,
    method: function () {
      console.log( this.attr1 );
    },
    fn1: fn1
  }
    
    
})();

alogy.singleton.method();
alogy.singleton.fn1();  

惰性单体

//惰性单体 (和闭包单体类似)

//通过 一个私有变量来控制是否 实例化对象, 初始化一个 init。

var Ext = {};

Ext.Base = (function () {

//私有变量 控制返回的单体对象
var uniqInstance; 

//需要一个构造器 init 初始化单体对象的方法
function Init () {
  
  //私有成员
  var a1 = 10;
  var a2 = true;
  
  var fun1 = function () {
    
    console.log( a1 );
    
  }
  
  return {
    attr1: a1,
    attr2: a2,
    fun1: fun1
  }
  
}

return {
  
  getInstance: function () {
    
    if ( !uniqInstance ) { //不存在 ,创建单体实例
      
      uniqInstance = new Init();          
      
    }
    
    return uniqInstance;
    
  }
  
}

})()

var init = Ext.Base.getInstance();

init.fun1(); //10

分支单体

//分支单体 (判断程序的分支 - 浏览器差异的检测)
//简单判断
var Ext = {};

var def = true; 

Ext.More = (function () {
  
  var ff = {
    attr1: 'ff'
  };
  
  var ie = {
    attr1: 'ie'
  }
  
  return def ? ff : ie;
  
})()

console.log( Ext.More.attr1 ); //ff

简单链式编程实现

简单链式调用。 return this;

//简单函数链式调用 

function Dog () {
  
  this.run = function () {
    
    console.log( 'dog is run...' );
    
    return this;
    
  }
  
  this.eat = function () {
    
    console.log( 'dog is eat...' );
    
    return this;
    
  }
  
  this.slepp = function () {
    
    console.log('dog is sleep');
    
    return this;
    
  }
  
}

var d1 = new Dog();

d1.run().eat().slepp();
   

模拟jquery底层代码

//模拟jquery底层链式编程
  
// 函数自执行 特点:
// 1: 程序启动时候  里面代码自动执行
// 2: 内部的成员变量 外部无法访问 (除了不加var修饰的变量)

//块级 作用域  

(function ( window,undefined ) {
  
  //$ 最常用的对象 返回给外界 //大型程序开发  一般使用 '_'作为私有的对象
    
  function _$ ( args ) {
    
    // 匹配id 选择器
    var idSelect = /^\#[\w+]?/;
    
    this.dom; // 接收所得到的元素
    
    if ( idSelect.test(args) ) { //匹配成功接收元素 // #div 
      
      this.dom = document.getElementById(arguments[0].substr(1));
    
    } else {
      
      throw new Error('选择器不正确!');
      
    }
    
  }
  
  //在Function类上 扩展 一个可以实现 链式编程的方法
  Function.prototype.method = function ( methodName,fn ) { //实现链式编程, 方法的名字 和 进行调用的函数是什么
    
    this.prototype[methodName] = fn;
    
    return this; //链式编程
    
  }
  
  // 在 _$ 原型对象上 加一些公共的方法
  _$.prototype = {
    
    constructor: _$,
    
    addEvent: function ( type,cb ) {
      
      //ff chrome
      if ( window.addEventListener ) { 
        
        this.dom.addEventListener(type,cb,false);
        
      //ie
      } else if ( window.attachEvent ) { 
        
        this.dom.attachEvent('on'+type,cb);
        
      }
  
      return this;
      
    },
    
    setStyle: function ( key,val ) {
      
      this.dom.style[key] = val;
      
      return this;
      
    }
    
  }
  
  //window上注册 一个 全局变量
  window.$ = _$;
  
  //准备方法
  _$.onReady = function ( cb ) {
    
    //1,实例化 _$ 对象 ,注册到 window上
    window.$ = function ( args ) {
      
      return new _$(args); 
      
    }
    
    //2: 执行传入的代码
    cb.call(window);
    
    //3: 实现链式编程 
    _$.method('addEvent',function () {}).method('setStyle',function () {});
    
  }
  
})( window ) //程序的入口 window传入作用域中      

$.onReady(function () {
  
  $('#div')
  .addEvent('click',function () {
    
    console.log('点击了');
    
  })
  .setStyle('background','pink')
  
});

严格模式

严格模式是JavaScript中的一种限制性更强的变种方式。
严格模式与非严格模式可以共存,可以逐渐的选择性加入严格模式。

全局作用域

定义变量必须通过var
严格模式禁止删除声明变量。

delete关键字

使用delete删除一个变量名(而不是属性名): delete myVariable

'use strict';

delete Object.prototype; // error . 
// 删除一个不可配置的属性

函数参数

定义相同名称的参数
要求参数名唯一。
在正常模式下,最后一个重名参数名讳覆盖之前的重名参数,之前的参数仍然可以通过arguments[i]来访问,还不是完全无法访问。

关键字,保留字

使用eval或arguments作为变量名或函数名

严格模式下:
访问arguments.callee, arguments.caller, anyFunction.caller以及anyFunction.arguments都会抛出异常

禁止使用八进制

浏览器都支持以零(0)开头的八进制语法:0644 == 420 还有 '\045 === '%''
认为数字的前导零没有语法意义,但是会改变数字的意义。

eval

严格模式下不能向全局作用域下添加变量

在正常模式下,代码eval('var x;') 会给上层函数或全局引入一个新的变量 x
严格模式下,eval为被运行的代码创建变量,eval不会影响到名称映射到外部变量或其它局部变量。

var x = 22;

var evalX = eval("var x = 42; x");

console.log(x === 22);
console.log(evalX === 42);

函数内部this

在正常模式下函数调用,this的值会指向全局对象,在严格模式中,this的值会指向undefiend。

当函数通过call和apply调用时,如果传入的是thisvalue参数是一个null和undefiend除外的原始值(字符串,数字,布尔值),则this的值会成为那个原始值的对应的包装对象。如果thisavlue参数的值是undefeind或null,则this的值会指向全局变量。在严格模式中,this值就是thisvalue参数的值,没有任何类型转换。

this: 仅在this指向自己创建的对象时使用它

arguments

arguments对象属性不语对应的形参变量同步更新。
非严格模式下,修改arugmetns对象中的某个索引属性的值,和这个属性对应的形参变量的值也会同时变化。
严格模式下,arguments对象会以形参变量的拷贝的形式被创建和初始化。因此arguments对象的改变不会影响形参。

arguments: 总是通过形参的名字获取函数参数,或者在函数的第一行拷贝arguments

var args = Array.prototype.slice.call(arguments)

with

严格模式禁用with。
with问题:块内的任何变量都可以映射到with传进来的对象的属性,也可以映射到包围这个块的作用域内的变量(甚至是全局变量),在运行时才能够决定:在代码运行之前无法得到。
严格模式下,使用with会引起语法错误。

var x = 7;
with (obj) { // 语法错误
 // 如果没有开启严格模式,with中的这个x会指向with上面的那个x,还是obj.x?
 // 如果不运行代码,我们无法知道,因此,这种代码让引擎无法进行优化,速度也就会变慢。
 x;
}

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结

希望本文所述对大家JavaScript程序设计有所帮助。

您可能感兴趣的文章:
阅读全文