1.构造函数中有一个prototype属性指向一个原型对象,而后原型对象中有一个constructor属性指行构造函数,因此它们才可以互相关联,若是你改变了构造函数的prototype属性所指向的原型对象如p.prototype={},那么如今这个原型的构造函数就会变成Object,天然就调用不了以前旧的原型中的方法了,由于当前的构造函数已经和新的原型进行了关联。 2.检测一个对象的数据类 ◆使用Object.prototype.toString.call(arr);,方法中传递一个对象的实例,就可以找到它是什么数据类型,可是这种方法没法检测出自动定义构造函数建立出来的对象的实例 ◆使用arr.constructor.name;也就是直接获取这个对象的构造函数的名称,既能够获取系统预约义的类型,也可以获取到本身自定义的构造函数建立出来的对象的实例的类型的名称,这种方式最会简洁,很是好。 3.js继承的三种方式 ◆给原型对象添加成员(经过对象的动态特性),可是这并非严格意义上的继承 ◆直接替换掉原来的原型对象,那么构造函数实例化的对象就可以调用新的原型对象中的方法和属性(使用这种方式实现继承的时候,颇有可能把以前原型中的属性和方法清空)。 ◆利用混合的方式给原型对象添加成员,就是使用for in 外加对象的动态特性,也可以把另外一个对象全部的方法都传给当前的对象(使用这种方式有可能会把原来原型中的同名方法或属性覆盖掉)。 4.扩展内置对象 ◆通常扩展对象的属性或者方法,会使用给原型对象添加成员(对象的动态特性),可是这种方式不适合用在js 的内置对象中,由于若是改了内置对象中的成员,那么其它地方须要用就没办法了,会形成冲突,因此不推荐这么使用。 ★扩展内置对象的方式可使用以下的方式【 //新建立一个构造函数 function MyArr(){} //替换掉这个构造函数的原型(也就是让它继承自新的类型) MyArr.prototype=new Array();//它的原型就是一个数组了,因而它就可以调用内置对象数组中的方法 var myarr=new MyArr(); myarr.push("1个球");//调用数组的方法 myarr.push("2个球","3个球"); console.log(myarr);//["一个球","2个球","3个球"] 】,MyArr的原型变成了一个数组的实例化对象,这个数组的实例化对象并不会影响数组的原型,因此能够随便往里面添加成员或修改原成员,不会影响数组对象。 5.原型链 ◆每一个构造函数都有原型对象 ◆每一个对象都会有构造函数 ◆每一个构造函数的原型也都是一个对象 ◆那么这个原型对象也会有构造函数 ◆那么这个原型对象的构造函数也会有原型对象 ◆循环往复就会造成一条链式结构,就称为原型链,而且到最终都会指向一个Object,Object的原型对象不存在,因此Object是最终的类型,也称之为基类(最终的类型) ◆对象.__proto__实际上等价于对象.constructor.prototype,也就是对象.构造函数.原型,可是最好不要动__proto__,由于会影响到构造函数的原型,这个属性通常用来测试,由于代码量不多,而且它并不在标准以内。 ◆当你替换掉当前构造函数的原型后要记得给这个构造函数的原型添加一个constructor属性,否则就有可能没法经过对象.constructor来获取当前对象的构造函数了【 Human.prototype=new Animal();//原型继承自Animal的一个对象 Human.prototype.constructor=Human;//可是本身仍是Human类型的 】。 6.对象的成员搜索原则 ◆当访问一个对象的成员的时候,会先在自身中去找(由于js中有对象的动态特性,固然对象也是由构造函数建立出来的),找到了那就直接使用,若是没有找到,那么就会去当前对象的原型中去找,找到了仍是直接用,若是没有找到,那么就会去当前对象的原型对象中的原型对象中去找,就这样一直找到最后一个原型对象(Object.prototype),若是仍是没找到,若是你访问的是引用类型则返回null,若是你访问的是基本类型则返回的是undefined,你访问的若是是一个方法,那么就会报错,由于null没法被看成方法来进行调用。 7.原型继承概念 ◆经过修改原型链结构来实现继承,就叫作原型继承 8.ECMAScript5经典继承 ◆使用一个方法Object.create()来实现原型继承:【 var object1={name:"zs"}; var obj=Object.create(object1); console.log(obj.name); 】 ◆兼容性写法,由于是ECMAScript5新增的一个方法: 【 var object1={name:"zs"}; //若是这个方法存在 才调用,首先检测浏览器是否有这个能力,若是没有就手动添加一个这样的方法,可是不推荐使用 if(Object.create){ //使用ECMAScript5中的经典继承方式 var obj=Object.create(object1); conosle.log(obj.name); }else { //手动添加一个这样的方法 Object.create=function(object1){ //自定义一个构造函数 function F(){} //使用原型继承的方式 F.prototype=object1; //初始化这个构造函数 并返回 return new F(); } var obj=Object.create(object1); conosle.log(obj.name); } 】 9.Object.prototype的成员 (如下的p代指一个对象) ◆constructor:原型对象内的一个属性,执行该原型对象相关联的构造函数【p.constructor】。 ◆hasOwnProperty:一个方法,用来判断对象自己(不包含原型)是否拥有某个属性【p.hasOwnProperty("name")】。 ◆propertyIsEnumerable:判断属性是否属于对象自己,判断属性是否能够被遍历【p.propertyIsEnumerable("name")】。 ◆Object.defineProperty(obj,prop,descriptor);能够用来添加属性,同时也能够用来附加一些信息,例如这个属性是否可写可读可遍历 【 obj: 须要被操做的目标对象 prop: 目标对象须要定义或修改的属性的名称 descriptor: 将被定义或修改的属性的描述符 var obj = new Object(); Object.defineProperty(obj, 'name', { configurable: false, writable: true, enumerable: true, value: '张三' }) console.log(obj.name) //张三 】 ◆toString()和toLocaleString():会根据操做系统来进行字符串的大小写转换,而且若是是日期的话还会进行地区时间的转换。 ◆valueOf:当对象参与运算的时候,默认会先去调用对象的valueOf方法,若是valueOf获取到的值,没法进行运算,那么就会去调用这个对象的toString方法,最终作的就是字符串拼接的工做了 ◆__proto__:是对象中的属性,会指向该对象的构造函数的原型对象,能够经过对象.__proto__去访问原型对象。 10.Function这个构造函数,能够用来新建函数对象 ◆var 函数名=new Function();,一个参数都不传递的状况下就是建立一个空的函数。 ◆var 函数名=new Function("函数体");,只传一个参数的状况,这个参数就是函数体。 ◆var 函数名=new Function("参数1","参数2","函数体");,传递多个参数的状况,最后一个参数为函数体,前面的参数都是该函数的参数名。 ◆解决使用传递的函数体过于长的问题【 ◇可使用+做为链接符号。 ◇能够定义一个模板,而后经过dom来读取模板中的字符串,而后将读取到的字符串做为函数体位置上的参数。 】 ◆解决使用传递的函数体过于长的问题2(ECMAScript6语法)【 //使用``来做为字符串的界定符号 var distinct=new Function(` var arr=[]; for(var i=0;i<arguments.length;i++){ if(arr.indexOf(arguments[i])==-1){ arr.push(arguments[i]); } } `) 】 11.eval函数能够用来将字符串转换为javascript代码而且运行 ◆使用eval来解析JSON格式字符串的时候,会将{}解析为代码块儿,而不是对象,因此须要在JSON格式的字符串前面拼接上var obj=,如【 var jsonData='{"name":"zs"}'; eval("var obj="+jsonData); console.log(obj);//{name:"zs"} 】。 ◆使用eval来解析JSON格式字符串的时候,会将{}解析为代码块儿,而不是对ixang,因此须要在JSON格式的字符串两边下上小括号,如【 var jsonData='({"name":"zs"})'; var obj=eval(jsonData); console.log(obj);//{name:"zs"} 】 ◆因为eval能够将字符串转换为js代码而且执行,因此可能会引起跨站点脚本攻击,因此不推荐使用eval,将JSON格式字符串转换为js对象,可使用JSON.parse();。 12.静态成员和实例成员的概念,是从其它变成语言中引入的 ◆静态成员:是指构造函数的属性和方法【 如jquery中 $.trim();$.each();.$.extends(); 】 ◆实例成员:是指实例的属性和方法【 如$("#id").css();$("#id").text(); 】 ◆通常都是把工具方法,做为静态成员(全局共享,而且添加起来仍是使用的对象的动态特性,构造函数的对象均可以调用) ◆通常把跟对象相关的方法,做为实例成员