js:语言精髓笔记13--语言技巧
消除代码全局变量名占用: //本质是使用匿名函数;
void function(x, y, z) {
console.log(x + y + z);
}(1,2,3);
//要使函数内的变量不被释放,需要使用引用;
一次性的构造函数: //维护原型链,保证标识符重写后,实例.constructor仍指向构造器;
var Instance = function() {};
Instance.prototype = {
constructor: Instance
}
Instance = new Instance();
Instance2 = new Instance.constructor();
对象充当识别器: //利用对象实例在全局的唯一性
//判断某个标识符是否存在函数内;
var obj = function() {
var yes = {};
var tab = {v1: yes};
return {
query: function(id) { return tab[id] === yes}
}
}();
obj.query('v1'); //true
//判断是外部调用还是内部调用;
var myFunc = function() {
var handle = {};
function _myFunc() {
if(arguments[0] === handle) {
console.log('in');
} else {
console.log('out');
}
}
Array.prototype.unshift.apply(arguments,[handle]);
_myFunc.apply(null,arguments);
return _myFunc;
}
var func = myFunc(); //in
func(); //out
识别构造器调用:
//唯一的问题是如果将构造器赋给实例为方法,则只能判断为new;
function MyObject() {
if(this instanceof arguments.callee) { // this.constructor === arguments.callee ;此方法注意维护constructor
console.log('new');
} else if(this === window) {
console.log('window');
} else {
console.log('object');
}
}
var obj1 = new MyObject(); //new
var obj2 = {}; obj2.func = MyObject;
obj2.func(); //'object'
MyObject(); //'window'
快速调用对象方法: //使用apply,call;
var obj = {};
[].push.apply(obj,[1,2]);
console.log(obj); //{0:1,1:2,length:2} ,会传入length;
//判断对象的hasOwnProperty属性是否被重写;
var obj = {
hasOwnProperty: function() {}
};
console.log({}.hasOwnProperty.call(obj, 'hasOwnProperty')); //true
//对String,Boolean,Number直接量使用该技巧,由于其会有隐式包装,所以会多一些开销;
日期计算:
//获取当前对应n天前的时间数据,然后用date的获取方法获取要获取的数据;
var getPrevDay = function (n) {
return new Date(new Date() - n*24*60*60*1000);
}
console.log(getPrevDay(1).getDate());
//获取两天差的时间; var d1 = new Date(2007,1,1,12,1,30,300);
var d2 = new Date(2006,10,15);
console.log(parseInt((d1-d2)/1000/60/60) + ' h');
console.log(parseInt((d1-d2)/1000/60/60/24) + ' d');
构造复杂对象:
//对象进行值运算;
var obj = {};
obj.valueOf = function() {
return 10;
}
console.log(10 * obj); //100
函数封装为方法:
aObj = {info: 'hello'};
aFunc = function() {console.log(this.info)}; function getMethod(obj, func) {
return function() {
return func.apply(obj);
}
}
m = getMethod(aObj, aFunc); //建立两者关系的函数
m();
//相当于
m2 = aFunc.bind(aObj);
m2();
构造函数参数:
//在当前数组中查找item,找到删除并用插入list,否则在最后插入list
Array.prototype.findAndInsert = function(item, list) {
item = this.indexOf(item);
this.splice.apply(this, [
item < 0 ? this.length : item, 1].concat(list)
);
}
var aPosition = 1, x = 100, y = 200, z = 300;
function foo(v1, v2, v3) {
var args = function() {
return [].splice.call(arguments, aPosition, 0, x, y, z), arguments; //
}.apply(this, arguments);
console.log([].slice.apply(args)); //[11, 100, 200, 300, 22, 33, findAndInsert]
console.log([].slice.apply(arguments)); //[11, 22, 33, findAndInsert]
}
foo(11,22,33);
利用钩子扩充函数功能:
//基本函数扩充
function myFunc1() {
console.log('myFunc1');
}
myFunc1 = function(foo) {
return function() {
console.log('hook');
return foo.apply(this, arguments);
}
}(myFunc1); myFunc1();
//原型方法扩充
Number.prototype.toString = function(foo) {
return function() {
var result = foo.apply(this, arguments).toUpperCase();
console.log('hook');
return result;
}
}(Number.prototype.toString);
//扩充后只执行一次
myFunc2 = function(foo) {
return function() {
myFunc2 = foo; //脱钩
console.log('hook');
return foo.apply(this, arguments);
}
}(myFunc2);
js:语言精髓笔记13--语言技巧的更多相关文章
- js:语言精髓笔记5----语言分类
计算模型:源于对计算过程的不同认识: 1.基于不同计算模型一般分为://教科书的一般分类 命令式语言: 函数式语言: 逻辑式语言: 面向对象程序设计语言: 2.基于程序本质分类: //编程的经典法则 ...
- js:语言精髓笔记12--动态语言特性(2)
对于括号内: 通过赋值时发生的重写: (Object1 = function() {}).prototype.value = 100; var obj1 = new Object1; console. ...
- js:语言精髓笔记11--动态语言特性(1)
语言:程序最终被表达为数据(结构)和逻辑(算法),命令式和说明式/函数式语言分别从这两方面分类: 动态:在语言陈述时无法确定,必须在计算机执行时才能确定语言关系:JS是完全动态语言,导致其不确定性一般 ...
- js:语言精髓笔记9--函数式语言特征
形式化运算系统的研究: 图灵:提出图灵机形式系统,通过0,1运算系统来解决复杂问题: 冯诺依曼:提出了冯诺依曼体系:即通过修改内存反映运算结果: 阿隆左.丘奇:提出新的运算范型Lambda演算,计算机 ...
- js:语言精髓笔记8--对象系统
封装: 一把对象系统,封装是由语法解析来实现的,即语法作用域:但js是动态语言,因此只能依赖变量作用域: js的变量作用域只有表达式,函数,全局三种:所以js只能实现public和private两种封 ...
- js:语言精髓笔记7----原型继承
面向对象有三个基本特性:封装,继承,多态:如果都满足的话称为面向对象语言:而部分满足则称为基于对象语言: 数据类型实现模型描述: JavaScript对象模型: 构造过程:函数->构造器 构造器 ...
- js:语言精髓笔记1--标识符与基本类型
标识符: 命名: 语法以及类型----语法关键字 //逻辑 值(的存储位置)----变量和常量 ...
- js:语言精髓笔记10--闭包
闭包: //JS函数式风格中,在内部保存数据和对外无副作用这两个特性主要就是通过闭包实现的: 函数与闭包: 一个函数是一段静态代码,它是一个代码书写时已经编译期,静态概念:闭包是函数在代码运行过程中 ...
- js:语言精髓笔记6----作用域
js基础语法:由语句.表达式和变量构成: 语句是主要表达方式:单语句->复合语句(代码块)->程序片段(函数):js中没有单元和程序的概念: 作用域: 语法作用域与变量作用域的区别:前 ...
随机推荐
- 后台返回json数据,前台显示代码
List list = "从DAL获取的数据集合" //取出分页标签html int pageIndex = context.Request["pageIndex&quo ...
- Protocol Buffers介绍
基本概念 Protocol Buffers(以下简称PB)是一种独立于语言.独立于开发平台.可扩展的序列化数据结构框架,它常常被用在通信.数据序列化保存等方面. PB是一种敏捷.高效.自动化的用于对数 ...
- DLL注入之注册表
0x00 唠叨 编写本系列文章纯属为了系统学习DLL注入的方法,所以很多方法可能已经过时,希望各位看官勿喷.当然若有更好的方法,希望不腻赐教.若本文有任何错的地方,也希望各位指正.谢谢! 0x01 适 ...
- iPhone socket 编程之BSD Socket篇
iPhone socket 编程之BSD Socket篇 收藏在进行iPhone网络通讯程序的开发中,不可避免的要利用Socket套接字.iPhone提供了Socket网络编程的接口CFSocket, ...
- openCV的基本操作
http://www.cnblogs.com/luluathena/archive/2010/09/29/1838471.html
- eclipse内存设置,tomcat内存设置,查看内存大小
首先可以通过java/jdk/bin下的java visualVM查看eclipse的内存大小和tomcat的内存大小,主要看堆,PermGen两个大小 如图: 多数情况下,eclipse抛出内存溢出 ...
- 2.16 最长递增子序列 LIS
[本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...
- 2.python基础深入(元组、字符串、列表、字典)
一,对象与类 对象: python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,玩的手机就是对象. 我们通过描述属性(特征)和行为来描述一个对象的. 在python中,一个对象的特 ...
- ubuntu 13.10 amd64安装ia32-libs
很多软件只有32位的,有的依赖32位库还挺严重的:从ubuntu 13.10已经废弃了ia32-libs,但可以使用多架构,安装软件或包apt-get install program:i386.有的还 ...
- Eclipse设置C++自动补全变量名快捷键Alt + /
使用快捷键:Alt+/ 要是还是有些场合不能提示,按照下列步骤 Window-Preferences-c/c++-Editor-Content Assist-Advanced 将未勾选的全部勾选