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中没有单元和程序的概念: 作用域: 语法作用域与变量作用域的区别:前 ...
随机推荐
- iphone数据存储之-- Core Data的使用(一)
http://www.cnblogs.com/xiaodao/archive/2012/10/08/2715477.html 一.概念 1.Core Data 是数据持久化存储的最佳方式 2.数据最终 ...
- poj2993 翻转2996
Emag eht htiw Em Pleh Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2944 Accepted: ...
- php 二分查找
<?php /**二分查找:查找一个值在数组中的位置 * @$arr:操作的数组,前提是按顺序排列 * @$val:查找的值 * @$start:查找的起始位置,默认从数组的第一个数找起 * @ ...
- 【系统】CentOS、Ubuntu、Debian三个linux比较异同
CentOS.Ubuntu.Debian三个linux比较异同 2014-07-31 12:58 53428人阅读 评论(6) ...
- FireFox下上传控件的显示问题
Chrome正常 FireFox显示不正常 上传控件一直有个问题,就是样式问题,解决方法就是用一个大的背景层挡住,然后点大的背景层去触发上传控件的Click事件. Html: <span id= ...
- net发送邮件
对于.NET而言,从2.0开始,发邮件已经是一件非常easy 的事了.下面我给出一个用C#群发邮件的实例,做了比较详细的注解,希望对有需要的朋友有所help.看了这篇BLOG,如果你还不会用.NET发 ...
- Sybase IQ导出文件的几种方式
IQ有四种方法,将表的数据导出为文本文件:1.重定向 SELECT * FROM TABLE1 ># D:MYDATATABLE1.TXT -- 文件生成在执行语句的客户端上 2.通过选项导出 ...
- iOS的 context 和Android 中的 canvas
ios 想要绘图,要用到CGContextRef类.最基本的用法是在- (void)drawRect:(CGRect)rect 函数中绘制. Android 中要用到Canvas类.最基本的用法是在 ...
- 【python】pathlib库
pathlib在python3.2以上开始默认支持,在python2.7中如果要使用需要安装 pip install pathlib pathlib更多参考资料:http://pathlib.read ...
- java 执行command
StringBuffer buf = new StringBuffer(1000); try { Process pos = Runtime.getRuntime().exec("sh &q ...