你会如何给全局对象添加toString()方法
首先,在讨论如何给所有方法window对象添加toString方法的时候,我们先来说说window的对象继承与对象实例,以及构造函数的this指针,还有变量的提升与方法的调用方式,最终一探window对象与Window方法(函数)的处理方式。
在说window对象之前,请让我们一起写一个实例的方法暖暖身,跳水之前应该做热身动作,虽然我们不跳水,不过写代码也需要做一个热身,这样才能适应下面的高难度动作。
废话好多,裁判看不下去了,开始准备你的姿势,让我们开场就拿个满分,吓一下裁判(平时我也常被人吓,感觉被同化了一样),但是看到裁判吓到自己可不好了!俺表示自娱完了,该准备一下迎接下一场,go.....。
var fun = new Object();看到这个你一定不会陌生,这个就是一个实例,相比var win = new window();其实这样就会出错,错的很明显,全局属性本身就是一个实例对象。所以我们就要写一个相对于object对象的实例的一个对象才能输出Object {},var win = new window.Object();这样就不会出错了。这个win就是一个实例,那么实例也可以简化一下,如var win = {}。
此刻,你是否在想,如此我想把全局window也写成自己的,哇哇,这个建议不错,可以一试,于是乎,我们马上就写一个能替换浏览器的全局属性,var window = {};输出一个全局的空对象,一点也没问题,但是却少了浏览器特有的属性,这个是当然,我们等会儿再说,这里留个悬念。
主帅说,你这次跳水,跳的还是一般般,给的感觉是没以前标准了,于是,主帅拍拍我的肩膀,小伙子,加油!我知道这是给我打气,给我加油,看到楼下的观众都在看着自己,于是我装作谈定,噗通一声,一跃而下,嘛呀,你TM在逗我吗,这样就结束了。
当然了,不然我这代码写到神马时候,快凌晨一点,谁会在这里看你,速度点吧(半夜头脑最清醒)。
现在我们在实例一次,var fun = new Function();相比这个也很熟悉吧,如果你觉得哪里看到过,那么你就知道Function才是一个完整的构造函数。那么简化的函数应该怎么写呢,function fun(){};这里就是一个简写的,可扩展的构造函数,有了这个条件,你肯定在想,既然能扩展,那我是不是可以给函数加点料,让函数变得更加的灵活,于是,就有以下不同的函数书写方式,如:var koringz = function(){};看到这个,你会觉得,是不是还能再给函数加点料,var koringz = function koringz(){};看起来有点耀眼,你嘛的光环这么多,我TM怎么认识你,各种装B技能都集中在一起,能不能再牛逼点吗?老子就是想看看这几个字母能组合多少次,说组合就组合,(function(){})();一种,var koringz =(function(){})();二种,! function(){}()三种,+function(){})()四种。我眼睛不好,你还是慢点吧,我们还是慢点组合,说着说着就没了,可能我都觉得这没的也太快了。如果你觉得还有更多的,还可以继续加点料,萌萌の!
有了以上各种逼格,你还觉得这些都不够给你装逼。那么下面,我想该动动真家伙了,技巧为上,有了技巧可能会比没用技巧的略胜一筹,那还等什么了,说干就干呗。
我们就定义一个window全局变量,然后给这个window对象赋予各种自定义属性,
var window = {
top:'window',
local:'local',
Window:function(){},
Attr:function Attr(){},
koring: koringz,
zsg:zsg,
tr:trs,
wyz:weiyuzhou,
call:cal
};
这些属性你都熟悉吧,瞧一瞧,看看有么看得顺眼,过一篇有么有记住名字。
下面我给它传递方法添加属性:
var koringz = function korings(){
koringz.toSTR = function(){};
koringz.build = ['tostr','defined tostring’];
this.CHECKING = '1';
}
var zsg= function(){}
var weiyuzhou = function weiyuzhou01(){}
var tostr = function(){}
koringz.prototype.util = function(){}
koringz.prototype.util2 = function(){}
koringz.prototype.util3 = function(){}
koringz.prototype.util4 = {};
koringz.prototype.util5 = {};
koringz.prototype.util5 = ['2014-2015-2016']
koringz.prototype.util6 = '2014-2015-2016'
有了以上这些自定义函数表达式,下面我们是否可以去实现全局的获取,如若我想马上看到效果,现在是否有些急了点,还记得我们最初承诺了什么,我要给window绑定继承和this指针,甚至加上实例。对的,下面我们就一一给这个全局对象架上各种脚架,好让window对象有更多的技能释放,小心别被这些技能雷倒了。
于是乎,我们先实例一次:var po = new window.koring();然后干什么,直接迎接技能吗,我觉得还是再蓄点能量,等会儿好一起接个大招,一个个接会很累的,还不如放一起处理得了,Good好主意,就这么定了。
那么,我们再给po定义一个变量传递var pon = po;。接着我们再给函数套上继承pon.__proto__ = po.prototype;。随后我们再看看函数的调用的时候,this指针是否改变了,继承是否也改变了。
通过console.log(window);console.log(pon.util6= po.util6);你有么有发现,window属性koring下的koringz变量定义的都提前处理了!
arguments: null
build: Array[2]
caller: null
length: 0
name: "korings"
prototype: korings
toSTR: ()
tostring: ()
__proto__: ()
还有输出util6的布尔值都为true,哇哇,好厉害呀,别太鸡冻,原来我们在koring函数内部定义的this指针的属性没有被添加进来this.CHECKING = '1',但是通过koringz定义的属性添加进来了build: Array[2] toSTR: (),说明此时的指针改变了,是通过koringz来实现的,那么此时的this指向了哪里?顺着这个问题,我们发现this指向了其他地方,原来this指针总是指向函数名korings,并不会指向变量名koringz。输出this看到结果如下:
korings {CHECKING: ""}
CHECKING: ""
__proto__: korings
This指针却能透过变量拿到prototype上的方法名。
.__proto__: korings
.constructor: korings()
.util: ()
.util2: ()
.util3: ()
.util4: Object
.util5: Array[]
.util6: "2014-2015-2016"
.__proto__: Object
然而,我把koringz.checking下面绑定一个this指针,看看能不能间接拿到prototype下面的CHECKING方法。发现给变量绑定的属性不能获取到继承的CHECKING方法,因此,我们知道var koringz变量的对象属性是不能直接被调用的,不过var koringz变量的对象属性是可在外部被保存起来的。korings方法上的对象属性是可以被直接调用的,不能被直接保存,所以我们要把korings方法上的对象属性保存起来,就要在var koringz变量的对象属性上绑定一个this.属性赋予给左边的变量的对象属性上,如此即可间接通过var koringz变量的对象属性保存一个korings方法的属性参数值。因此,你可以脑洞大开,通过这个去套用很多动态数据传递,恭喜你获得一次上升的机会。
接下来,我们看看能否调用到原型上的属性,也就是变量的对象属性或是变量的方法属性,看到这个关系有点复杂,心想this就是一个函数名,那么我是否可以把变量的指针绑定到this的指针上呢,所以我就要给这个变量绑定一个this,如此koringz = this我们就可以间接的转变成直接的从变量的对象属性上拿到一个值或是一个方法,而且这时候,我们不仅能拿到变量上的对象属性,还能保存变量的对象属性的输出值和方法,并且还能在外部被调用,真的是一举多得。小伙伴们,我有点困了,我只能写这么多了。
不过么讲完,我还是速度点吧。
下面我在想如何给window对象下全部子对象添加一个toString属性呢,我们发现浏览器的window对象都是有一个字符串的方法 被调用,于是我们也可以实现这个tostring方法,那么我们就用in来为每一个window对象添加一个方法,其实,我们也可以为每一个函数表达式添加toString方法,只不过这样不太理想了,于是我们就用如下方法,简洁明了:
var stostr= function stostr(){}
for(var p in window){
if(typeof window[p] == 'function'){
window[p].toString = stostr
}
}
看到输出值,每一个方法下面都有一个toString方法:
.Attr: Attr()
.arguments: null
.caller: null
.length:
.name: "Attr"
.prototype: Attr
.toString: stostr()
.__proto__: ()
.<function scope>
.__proto__: ()
.<function scope>
.koring: korings()
.arguments: null
.build: Array[]
.caller: null
.length:
.name: "korings"
.prototype: korings
.toSTR: ()
.toString: stostr()
.__proto__: ()
.<function scope>
.local: "local"
.top: "window"
此时,每一个方法都有一个tostring方法。是否觉得 so easy!
那么我们还要调用一次tostring方法,应该如何调用呢,对此,我觉得有了以上的基础,下面我们要给所有window对象的方法添加一个调用toString的方法,于是我们直接调用,这个肯定是不行的,他一定是建立在this指针上,所以,我们还是回到prototype继承的方法上,我们在原来的代码基础上进行一次修改,看看能否成立,在for in语句内部,我们实现一次继承:
window[p].prototype.tostring = function(){
return 'this is real tostring method'
}
接着我们输出二个实例的对象看看效果如何:
var cas_tr = new window.tr();
var cas_Attr = new window.Attr();
console.log(cas_tr.tostring() + '== ' + cas_Attr.tostring());
输出results:
this is real tostring method== this is real tostring method
这个成立!此问题到此结束。
如果你想要扩展toString资源,可以自己去研究,网上一搜一大推的事情,我就不说这个(Object.prototype.toString)。对于我这比较懒的人,一般都是用已经扩展好的方法,直接去生成一个字符串:
var s = (Math.random()).toString(22);
s.substring(2,22);
return "kcb0f95b4d2832j87d17"
得到一个随机的字符串。为此我想能理解的更彻底,而且说的要不一样,我特喜欢用自己的风格去处理,有空再去整合、扩展一下toString方法。
最后我们是否说点window对象和Window函数的不同之处了,你可能已经看出来了,一个是对象一个是函数当然不同了,对的,正如你看到的,Window下面的属性没有toString方法,所以我们就不必给Window函数下面添加字符串deep调用toString方法,不过你也可以自己去扩展。下面我想我该睡了。如果你觉得对你有用,请关注一下,谢谢大家。
你会如何给全局对象添加toString()方法的更多相关文章
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- 打印对象和toString方法
JAVA对象 java对象是都是Object类的实例,都可直接调用该类中定义的方法,这些方法提供了处理java对象的通用方法. > > 6.2.1打印对象和toString方法 先看 ...
- (64)Wangdao.com第十天_JavaScript 对象的 toString() 方法改变输出
JavaScript 对象的 toString() 方法改变输出 在平常,我们 console.log(对象); // 会打印 [Object Object] 但是我们想要更详细的输出,此时,我 ...
- JS高级---为内置对象添加原型方法
为内置对象添加原型方法 我们能否为系统的对象的原型中添加方法, 相当于在改变源码 我希望字符串中有一个倒序字符串的方法 //我希望字符串中有一个倒序字符串的方法 String.prototype. ...
- 275 原型与原型链:显式原型prototype ,隐式原型__proto__,隐式原型链,原型链_属性问题,给原型对象添加属性/方法
1.所有函数都有一个特别的属性 prototype : 显式原型属性 [普通构造函数的实例对象没有prototype 属性,构造函数有__proto__属性,原型对象有__proto__属性 ] 2. ...
- RegisterUserFunc为测试对象添加新方法或重写已有方法
QTP中为了提高扩展性,提供了一个为测试对象添加一个新的自定义方法,或者重写测试对象已有的方法的函数RegisterUserFunc,在此给大家分享一下. RegisterUserFunc:为测试对象 ...
- 第十三篇、Swift_Nav自定义返回按钮后或者隐藏导航栏,Pop返回手势失效的解决方法 Pop全局返回添加的方法
边缘的pop返回手势: override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.purple ...
- AspectJ之@DeclareParents注解为对象添加新方法
众所周知,AspectJ可以通过@Before,@After,@Around等注解对连接点进行增强,今天我们来玩一个新注解@DeclareParents.对目标对象增强一个新方法. 场景引入: 现在我 ...
- 为system对象添加扩展方法
////扩展方法类:必须为非嵌套,非泛型的静态类 public static class DatetimeEx { //通过this声明扩展的类,这里给DateTime类扩展一个Show方法,只有一个 ...
随机推荐
- Depth Buffer
Up until now there is only one type of output buffer you've made use of, the color buffer. This chap ...
- UVa 10213 How Many Pieces of Land ? (计算几何+大数)欧拉定理
题意:一块圆形土地,在圆周上选n个点,然后两两连线,问把这块土地分成多少块? 析:这个题用的是欧拉公式,在平面图中,V-E+F=2,其中V是顶点数,E是边数,F是面数.对于这个题只要计算V和E就好. ...
- Java8函数式接口之Predicate<T>
作用: 这是一个功能接口,因此可以作为lambda表达式或方法引用的赋值目标. 实例: /** * Created by luo on 2017/5/3. */ public class Predic ...
- Listbox 实现Item双击事件
void listBox1_MouseDoubleClick(object sender, MouseEventArgs e) { int index = this.listBox1.IndexFro ...
- 最短路(floyd/dijkstra/bellmanford/spaf 模板)
floyd/dijkstra/bellmanford/spaf 模板: 1. floyd(不能处理负权环,时间复杂度为O(n^3), 空间复杂度为O(n^2)) floyd算法的本质是dp,用dp[k ...
- 分布式集群环境下,如何实现session共享一(应用场景)
在web应用中,由于http的请求响应式,无状态.要记录用户相关的状态信息,比如电商网站的购物车,比如用户是否登录等,都需要使用session.我们知道session是由servlet容器创建和管理, ...
- vue教程4-vueadmin上手
项目地址 https://github.com/PanJiaChen/vue-admin-template 这是一个 极简的 vue admin 管理后台 它只包含了 Element UI & ...
- 题解 poj1845 Sumdiv (数论) (分治)
传送门 大意:求A^B的所有因子之和,并对其取模 9901再输出 (这题又调了半天,把n和项数弄混了QAQ) 根据算数基本定理:A=(p1^k1)*(p2^k2)*(p3^k3)*...*(pn^kn ...
- 【手撸一个ORM】第四步、Expression(表达式目录树)扩展
到这里,Orm的基架已经搭起来了,接下来就是激动人心的部分,表达式目录树转Sql语句,SqlDataReader转数据实体等等,但是在这之前,我们需要扩展下表达式目录树的方法,以方便后面的相关操作. ...
- 服务是如何加载并运行的, Kestrel、配置与环境
服务是如何加载并运行的, Kestrel.配置与环境 "跨平台"后的ASP.Net Core是如何接收并处理请求的呢? 它的运行和处理机制和之前有什么不同? 本章从"宏观 ...