js进阶篇:对象和原型

1.js中没有太明确的类的概念,每个function函数都可以看做是一个类,类中可以通过prototype属性来添加这个
类中的方法和字段。
2.一般情况把对象赋值或者添加到一个函数的prototype属性中,函数的prototype
对对象的值做出更改,对象本身也是会发生变化的,可以使用一种临时函数来打破这种关系链。
临时函数new F();

代码示例:
var obj = {x:0,y:1};
var F = function(){};
F.prototype = obj;
var f = new F();
console.log(f); 

//实例化之后 obj这个对象会挂在到f对象的原型中
f.x = "zs"; //这个时候其实是为f这个对象添加了一个自身属性。所有并没有对原型属性进行覆盖更改.
console.log(obj); //{x:0,y:1}; 所以这里的obj对象不会有任何变化,也就是说这里只是继承了它的原型属性。
如果浏览器支持ES5可以通过 Object.create();这个方法来直接使用,和临时构造器的函数等价

代码示例:
var f = Object.create({x:2,y:3}); 

3.一个函数使用prototype添加方法属性,和不使用prototype的区别:

function person(){}
person.name = function(){console.log("name")};  //相当于使用了静态方法  
person.prototype.age = function(){};     //通过new

由于使用了静态方法:调用的时候直接 person.name();即可 如果new了之后会出错
age属于对象的方式,需要new之后使用。
4.使用 hasOwnProperty 方法可以判断属性是否存在(用来检测是否含有自身属性)。
5.for...in 遍历对象时,只会遍历可枚举属性。
6.自身属性和原型属性

代码示例:
function func()
{
    this.name = "";    //自身属性
}
func.prototype.hello = "";   //原型属性

所谓自身属性通过构造器定义的属性,原型属性会挂载到prototype上。
通过 关键字 new之后会将属性挂载到这个func中,然后就可以通过for in关键字查找。

var f = new func();
for(var p in f)
{
   if(f.hasOwnProperty(b))  //判断是自身属性
      console.log(p);       //判断之后这里只会打印name这个属性
}

这里我们也是可以这样理解的:f.prototype == f.proto; //true

对象查询属性的方式,会首先在自身属性中去查找,如果查找不到的话会通过proto到对象的原型中去查找,如果
通过原型依然没有找到,会去原型对象的原型中再去查找,一直到找到或者属性为null的时候为止。这里也可以得出
一个结论:js的原型链的本质在于proto这个神秘的链接

7.对象可以通过 delete 删除指定对象的属性,当删除一个不存在的属性时也同样会返回true,用来删除变量和其他,可配置属性是无效的

示例:var a = "liu ying";
     delete a; //返回一个  false,严格模式下这样做的话会直接报错

8.Object.create()的使用
该方法接收两个参数,第一个参数是一个对象,第二个为可选参数。通过对象的属性进一步描述。传入一个对象后
返回值会继承传入对象的属性,通过对该返回值做修改,传入的远对象值不会随着变化。

代码示例://
var a = {name:"liu ying",age:23};  
var b = create.Object(a);
b.name = "hello";  //对返回值做修改
console.log(a);    //{name:"liu ying",age:23}   这个时候a对象的值的属性依然不会变化。
所以从这个属性可以看出,打破了原有的引用关系链。

9.内置构造函数的原型是只读的,Object.prototype = "liu ying",比如这样设置,不会报错,但是赋值是没有
生效的。
10.hasOwnProperty可以用来检测当前的属性是否是对象的自身属性,如果是继承的属性将会返回false
11.constructor属性:所有的对象都会从他的原型上去继承一个constructor属性,函数其实也是属于一种特殊的对象。

代码示例:
var a = function(){};
var b = new a();
b.constructor == Object;   //这里是返回一个true;
但是有些js的内置对象,不通过实例化的方法也可直接比较,也会返回true。
比如:
document.constructor == Document;
document.form3.constructor == Form;

12.proto属性:该属性是一个访问器,(一个getter函数和一个setter函数),它公开访问它的对象的内部prototype属性(对象或null)。
proto的使用是有争议的,尽量不要使用
13.Object.defineproperty()属性
该属性具备三个参数,第一个为目标对象,第二个为目标对象的key值,第三个参数为对象配置参数.详细说明一下第三个参数
第三个参数和设置一般对象一样,可以设置是否可枚举(enumerable),是否可配置(configrable),是否可写(writable);
这里默认都是false.
如果设置不可枚举,for.. in 的话是无法遍历出来内置的不可枚举属性的。通过Object.defineproperty可以创建对象
属性:

代码示例
var o = {x:0,y:1};
Object.defineproperty(o,"z",{
    configrable:true,
    enumerable:true,
    writable:true,
    value:5
});
console.log(o);    //{x:0,y:1,z:5}

除了添加可配置的属性,还有一个特别强大的功能,就是get和set方法,配置get和set方法以后可以检测当前属性的变化
如果属性值变化的话,会自动触发set方法.

代码示例:
var o = {x:0,y:1};
Object.defineproperty(o,"x",{
    configrable:true,
    enumerable:true,
    writable:true,
    get:function()
    {
        return this.x;
    },
    set:function(newVal)
    {
        this.x = newVal;
    }
});
//这里的get和set如果我手动修改了o.x的值的话,set方法就会自动触发,然后get方法返回值。
o.x = 2;   //这个时候set方法就会触发

14.Object.freeze()属性可以冻结一个对象,使该对象为只读。如果一个对象的属性也为对象,则冻结无效,如果
需要彻底的冻结的话就要使用递归来层层使用 freeze()属性来设置。
15.Object.getOwnPropertyDescriptor();该方法带两个参数:对象和key,通过key查找该对象的自身属性,然后会返回
当前对象的一些信息(value,是否枚举,是否可写)等等.
16.getOwnPropertyNames(),接收一个参数,需要是一个对象类型,根据传入的数据返回一个数组(当前的对象的key值);和Object.keys相比
个人觉得还是有一点相似之处的,不同的是该属性包括不可枚举的属性名也会一起返回。
17.Object.getPrototypeOf() 接收一个对象,能够返回该对象的原型。

代码示例:
var Vue = function(){};
Vue.prototype.hello = function(){};
var vue = new Vue();
//这里把vue这个对象传入 
var v = Object.getPrototypeOf(vue);
console.log(v);  //{hello:function(){}}  

18.Object.is()属性,接收两个值,判断两个值是否完全相等,返回一个布尔值。
19.Object.isFrozen() 方法判断一个对象是否被冻结(frozen)。 这里的冻结指的是所有的配置属性都是冻结状态,才会返回true
20.obj.propertyIsEnumerable(prop);可以判断该对象的当前属性是否可枚举。

你可能感兴趣的:(js进阶篇:对象和原型)