JS核心

127 阅读3分钟

window变量与window对象不是一回事

我的理解:

  • window变量指的是一个将内存地址具象化的名字
  • window对象指的是存在于heap中的一包方法
console.dir(window); // 看一下window所指的Window对象的结构
var x=window; // 让x引用window的地址
console.dir(x); //看一下x所指的对象的结构

运行结果: 同理:console与console对象也不是一个东西,Object与Object对象也不是

创建了一个空对象,空对象.toString()方法是如何来的呢?

var obj={}; obj.toString(); // 明明是空对象为什么会有toString方法呢?

答案是:继承自Object对象的.prototype属性

若篡改一个对象的值,则所有引用此对象地址的变量也会受到改变

var a ={"name":"frank"};
b=a;
b.name="ryan";
console.log(a); // {name: "ryan"}

为什么var obj1.toString=1 并不会让obj2.toString的值为1

答案:私有属性与公有属性不可混为一谈
obj1与obj2在初始化完成后首次调用toString方法时,其实都是调用“obj1/obj2.双下划线proto.toString”,利用隐藏属性的方式去调用一个公用的方法。

var obj1={},obj2={};
obj1.toString=1 // 创建私有属性并赋值,不会影响公有toString
console.log(obj2.toString) // 调用公有属性

执行一个方法时会在私有空间先找,找不到再去调用公有空间的

var obj1={};
console.log(obj1.toString); // 刚初始化,toString只在共有空间
obj1.toString=123; // 人为在私有空间创建toString
console.log(obj1.toString); // 123 现在在私有空间就可以找到toString了就不会继续找了

如何才能修改公用的toString?

var obj1={};
obj1.__proto__.toString=123; // 篡改公有方法
var obj111={};
console.log(obj111.toString); // 123

只要一个对象是大写的比如Object,那么它必定有一个prototype与--proto--

但是如果是小写的对象则就没有prototype prototype与--proto--的区别

  • 都存放相同的地址,地址指向一个公有空间
  • prototype只存在于大写对象上
  • --proto--存在于所有的对象上,不管你是私有空间(你创建的一个obj)还是公有空间(Array.prototype)

Object.prototype.--proto--为null

为什么arr可以调用hasOwnProperty?

答案:Array.prototype.--proto-- === Object.prototype
如图所示:先在arr自身找,没找到去Array.prototype找,没找到去Array.prototype.--proto--去找,也就是在 Object.prototype这个公有空间找结果找到了

题目

var a=[1,2,3];
b=a;
b.push='xxx';
a.push(4); //为什么报错说push不是一个方法?

b与a共享一个空间,在b身上加了个push属性则相当于a与b自身这个空间上加了个属性,当a.push时是先找这个自身空间然后再找--proto--的公用空间。

一个问题为什么Array.functionABC=1 不能让儿子arr接收到functionABC

我猜想要让新生的儿子继承到自己的属性的话不能是通过这种.的方式去赋值的而是要构造函数

toString 为什么不等于 Array.prototype.toString?

答案:toString是在Array.--proto--身上的,与Array.prototype不是同一处

Obejct是一个全局函数,可以用来生成对象,而var object只是一个变量名

每个对象都有一个隐藏属性,用来保存其原型的地址,这个隐藏属性的名字叫做 proto