window 的实例化,比Object.prototype.test = "right";早。var $A1 = new Object(); var $t1 = $A1.test; Object.prototype.test = "right"; var $B1 = new Object(); var $t2 = $B1.test;
我的例子里是直接用变量test,不是对象的属性。且看这个test为什么修改不了。Object.prototype.test = "right"; console.log(test); //right test = "wrong"; console.log(test); //怎么还是right?
貌似不对的。你一直在申明window是在设置原型的test属性之前就创建的,这能说明什么呢? var $A1 = new Object(); var $t1 = $A1.test; //在设置原型的test值之前就取值,那自然 Object.prototype.test = "right"; var $B1 = new Object(); var $t2 = $B1.test; var $t11 = $A1.test; //敢问这里不是能取到right么? window.console明明是存在的。console是怎么实现的我已经在上文提出来了,我是来探讨的,交流的,不是来提问的。chrome的console的实现是这样: eval("with(commandLineAPI){"+code+"}"); //一个eval套一个with块
哦是存在。 你这样看看。 test = 'gss'; Object.prototype.test = "right"; var $c = window.console.log(test);
!!!,原来是这样的,上面的有一些观点是错的,不理了 function MyConsole(obj){ this.global = obj; } MyConsole.prototype.log = function(key){ alert(this.global[key]); } function myWindow(){ this.test = 'wrong'; this.console = new MyConsole(this); } myWindow = new myWindow(); myWindow.console.log('test');Object.prototype.test = "right";var console = new MyConsole({}); console.log('test');
该过来 function MyConsole(obj){ this.global = obj; } MyConsole.prototype.log = function(key){ alert(this.global[key]); } function myWindow(){
this.console = new MyConsole(this); } win = new myWindow(); win.test = 'wrong'; win.console.log('test');Object.prototype.test = "right"; var console = new MyConsole(new myWindow()); console.log('test');
越说越乱。 不过我注意到了一点。 test = 'gss'; ///放断点. 在console中看.Object.prototype.test = "right";///放断点. 在console中看.
不理了,霸王硬上弓。 function MyConsole(obj){ var top={}; for(var i in Object.prototype){ top[i]=Object.prototype[i]; } var low = {}; for(var i in obj){ low[i]=obj[i]; } function merge(o,d){ for(var i in d){ o[i]=d[i]; } } merge(low,top);
this.global = low; } MyConsole.prototype.log = function(key){ alert(this.global[key]); } function myWindow(){ this.test = 'wrong'; this.console = new MyConsole(this); } win = new myWindow(); win.console.log('test');
Object.prototype.test = "right";
var console = new MyConsole(win); console.log('test');
if(test=="right")score++;
}()
void function(){
if(test=="wrong")score++;
}()函数表达式分两种,常用的匿名函数表达式(Anonymous Function Expression AFE)和命名函数表达式(Named Function Expression NFE)。他们的共同点是,都是函数表达式,和函数声明有本质区别。唯一不同的是,命名函数表达式内部可以通过函数名来访问函数自身(arguments.callee被废除),而这个函数名却不对外渗透。参见js版置顶帖【你自认为理解javascript?】第二题。ES对这个特性的规定是使用类似"new Object()"的形式创建一个特殊对象,这个对象只有一个属性,命名函数表达式的名字,指向这个函数的引用,并将这个特殊对象压入匿名函数表达式的作用域链顶端。这就解释了本例中,命名函数表达式查找test得到继承自Object的("right"),而匿名函数表达式查找test得到的是window下的("wrong")。然而新版本已经更正了此问题,特殊对象已经不再继承自Object,因此,本例中匿名函数和命名函数内部的test都应该是window.test。测试chrome版本 33.0.1750.149 ,发现情况根本不是这样。分析得,从开发者工具F12粘贴入代码,代码是通过eval运行的,并且,使用了with(commandLineAPI){ // your code} 进行包裹。这个commandLineAPI对象提供了命令行可以直接访问的诸多API,而它是继承自Object的,因此代码从作用域链顶端的withBlock Scope找到test值。新建html粘贴入代码则此二例子test值皆为"wrong",表现正常。======================================================var e="right";
try{
throw new Error;
} catch(e) {
e="wrong";
if(test=="right")score++;
}
if(e=="right")score++;catch块中的代码执行的时候,作用域链顶端会插入catchBlock Scope,这个异常e就是在这里声明的。按出题者所述,这个catchBlock Scope也是控制作用域的特殊对象,因此test值在这个特殊对象中找到,值为“right”。然而现在的浏览器对控制作用域的这种内部特殊对象都做了修正,他们不再继承自Object(同命名函数表达式)。至于变量e,catch内部的e来自catchBlock scope,因此catch内部修改e对外部没有影响。这个解释通了。相同的还有finally块。======================================================var f;
void function f(){
}
if(typeof f=="undefined")score++;这个很好解释,命名函数表达式,f值只对函数表达式内部有效,不会渗透到外部作用域。因此f还是undefined。chrome解析正确。
======================================================var err;
function a(){
var m="right";
var n;
return function(){
var err;
return arguments[0].call(this,arguments[1]);
}
}
try{
var b=a();
if(b(eval,"m")=="right")score++;
} catch(err) {
}
这个涉及到js引擎对eval的处理。按题意,m值应该可以正确获取,但是现代浏览器对eval的处理更多的想一个保留字,eval使用不当会影响js的优化。因此现在的处理方式是,如果直接使用eval,则eval会引用当前EC的scope chain,如果间接使用eval,则scope chain中只有global。因此这个m应该是获取不到的。换成这样便可:var err;
function a(){
var m="right";
var n;
return function(){
var err;
return eval(arguments[0]);
}
}
try{
var b=a();
if(b("m")=="right")score++;
} catch(err) {
}
window.test = "wrong" 这个观点吗?
不是的,不是这么简单。你在chrome的开发工具的console下粘贴以下代码,就知道了://先粘贴这一段
var test = "wrong";
Object.prototype.test = "right"
console.log(test); //wrong对不对?//接着第二次再粘贴这段代码
console.log(test);//right了?灵异了?
修正一下,问题不是这么重现的,应该是这样:Object.prototype.test = "right";
console.log(test); //right
test = "wrong";
console.log(test); //怎么还是right?
var $t1 = $A1.test;
Object.prototype.test = "right";
var $B1 = new Object();
var $t2 = $B1.test;
我的例子里是直接用变量test,不是对象的属性。且看这个test为什么修改不了。Object.prototype.test = "right";
console.log(test); //right
test = "wrong";
console.log(test); //怎么还是right?
Object.prototype.test = "right";
console.log(test); //right
test = "wrong";
console.log(test); //怎么还是right?这个例子是我在chrome的console下手动一行一行敲的,和一起复制粘贴不是一回事,每一次敲回车是一次执行,而每次执行是在不同的with块中,因此就会出现这个怪异的问题。with块的临时作用域在上文有解释,即with(commandLineAPI){//code }。
你这Object.prototype.test = "right";在他生成后才设值的。
2window.console 这方法不存在, 所以console 不属于window.
3.搞不好 console是这样写的
window.test = 'wrong';
Object.prototype.test = "right";
function wrapConsole(){
var global={};
for(var i in Object.prototype){
global[i] = Object.prototype[i];
}
return function (key){
// test 在 说不好是Object函数 的一个closure层里面的值;
// 先找Object 中的 test,找不到window中的test.
alert(global[key] || window[key]);
}
}
myConsole = wrapConsole();
myConsole('test');
var $t1 = $A1.test; //在设置原型的test值之前就取值,那自然
Object.prototype.test = "right";
var $B1 = new Object();
var $t2 = $B1.test;
var $t11 = $A1.test; //敢问这里不是能取到right么?
window.console明明是存在的。console是怎么实现的我已经在上文提出来了,我是来探讨的,交流的,不是来提问的。chrome的console的实现是这样:
eval("with(commandLineAPI){"+code+"}"); //一个eval套一个with块
你这样看看。
test = 'gss';
Object.prototype.test = "right";
var $c = window.console.log(test);
function MyConsole(obj){
this.global = obj;
}
MyConsole.prototype.log = function(key){
alert(this.global[key]);
}
function myWindow(){
this.test = 'wrong';
this.console = new MyConsole(this);
}
myWindow = new myWindow();
myWindow.console.log('test');Object.prototype.test = "right";var console = new MyConsole({});
console.log('test');
function MyConsole(obj){
this.global = obj;
}
MyConsole.prototype.log = function(key){
alert(this.global[key]);
}
function myWindow(){
this.console = new MyConsole(this);
}
win = new myWindow();
win.test = 'wrong';
win.console.log('test');Object.prototype.test = "right";
var console = new MyConsole(new myWindow());
console.log('test');
不过我注意到了一点。
test = 'gss';
///放断点. 在console中看.Object.prototype.test = "right";///放断点. 在console中看.
function MyConsole(obj){
var top={};
for(var i in Object.prototype){
top[i]=Object.prototype[i];
}
var low = {};
for(var i in obj){
low[i]=obj[i];
}
function merge(o,d){
for(var i in d){
o[i]=d[i];
}
}
merge(low,top);
this.global = low;
}
MyConsole.prototype.log = function(key){
alert(this.global[key]);
}
function myWindow(){
this.test = 'wrong';
this.console = new MyConsole(this);
}
win = new myWindow();
win.console.log('test');
Object.prototype.test = "right";
var console = new MyConsole(win);
console.log('test');