标签:基本数据类型 工厂 box 包括 修改 实参 构造 属性的方法 apply
目录
把描述同一事物的属性放进同一个空间地址下,避免了全局变量的干扰,这种开发的模式就是单例模式。
var singleton1={
fn:function{
}
}
var singleton2={
fn:function{
}
}
singleton1.fn();
singleton2.fn();
采用了自执行函数闭包的作用,保护里面的私有变量不受外界的干扰;同时,如果在闭包外面使用里面的函数时,可以把其return作为返回值。
var niu = (function () {
var num = 1;
var niuCode = {
fn:function () {
console.log(num);
},
sum:function () {
console.log(num);
}
}
return niuCode;//niuCode只是一个空间地址,所以定义一个niu来接收它。
})();
box.onclick = niu.fn;
把实现同一功能的代码放到一个函数中,当想实现这个功能时,执行这个函数即可;减少了代码的冗余,“高内聚,低耦合”,实现了函数的封装。
function createPerson(name,age) {
var obj ={};// 创建一个对象
obj.name = name;// name获取形参的值
obj.age = age;
return obj;//return 出一个对象
}
// p1接收了createPerson 的返回值;
var p1 = createPerson("张三",12);
var p2 = createPerson("王五",30);
new
:操作符,在函数执行前加new
类:内置类和自定义类;所有的类都是函数;
实例:通过构造函数或者类new出来的都是一个实例。
普通函数和构造函数区别
构造函数的特征
instanceof
:检测当前实例是否属于这个类的方法,属于返回true,不属于返回false。hasOwnProperty
:检测当前属性是否是私有属性,如果是返回true;不是返回false实例.hasOwnProperty(属性)
//封装一个检测共有属性的方法
function hasPublicProperty(obj,attr){
if(obj[attr}){//由于传入的参数是字符串,所以不能用obj.attr,可以用obj[attr]或者attr in obj;
if(obj.hasOwnProperty(attr)===false){
return true;
}else{
return false;
}
else{
return false;
}
}
}
hasPublicProperty(obj,"tostring")
//优化以后
function hasPublicProperty(obj,attr){
return attr in obj && !obj.hasOwnProperty(attr)?true:false;
}
hasPublicProperty(obj,"tostring")
__proto__
的属性,这个属性的属性值指向当前实例所属类的prototype(如果不能确定它是谁的实例,都是object的实例,即object.prototype)它是一种基于
__proto__
向上查找的机制。当我们操作实例的某个属性或者方法的时候,首先找自己空间中私有的属性或者方法
- 找到了,则结束查找,使用自己私有的即可
- 没有找到的话,则基于
__proto__
找所属类的prototype,如果找到,就用这个共有的,如果没找到,基于原型上的__proto__
继续向上查找,一直找到Object.prototype的原型为止,如果再没有,操作的属性或者方法不存,得到undefined。这样通过__proto__向上查找就会形成一个原型链。
在实际项目基于面向对象开发的时候(构造原型设计模式),我们根据需要,很多时候会重定向类的原型(让类的原型指向自己开辟的堆内存)
当我们需要给类的原型批量设置属性和方法的时候,一般都是让原型重定向到自己创建的对象中
Fn.prototype={
aa:function()
}
存在的问题:
自己开辟的堆内存中没有consturctor属性,导致类的原型构造函数缺失。
解决:手动在堆内存增加constructor属性
内置类:内置类扩展时,如果和内置的方法名相同,会对其进行覆盖。但是内置类原型的空间地址不可以被修改,只能向其中新增一些方法。所以类.prototype={}只适用于自定义类,不能用于内置类,比如Array等这些内置类。
私有属性和公有属性
__proto__
找到的属性,想对自己来说是公有的基于内置类的原型扩展方法,供它的实例调取使用
//实现数组的去重
Array.prototype.myUnique=function myUnique(){//后边函数的名字可加可不加
//方法中的this一般都是当前类的实例(也就是我们要操作的数组)
var obj={};
for(var i=0;i<this.length;i++){
var item=this[i];
obj.hasOwnProperty(item)? (this[i]=this[this.length-1],this.length--,i--):obj[item]=item;
}
obj=null;//释放堆内存
return this;
};
ary.myUnique();
//链式写法求数组最大值
var max=ary.myUnique().sort(function(a,b){return a-b}).pop();
JS的链式写法
保证每一个方法执行返回的结果依然是当前类的实例,这样就可以继续调取方法使用了
ary.sort(function(a,b){return a-b}).reverse().pop();
//执行完返回的结果是删除的那一项的值,所在再调用数组方法会报错,也可以接着使用其它内置类方法
创建变量之字面量创建和实例创建
var a=1;
var a1=new Number(1);
instanceof
进行检测typeof
进行数据类型的检测,都返回"object"
可枚举属性和不可枚举属性
用for...in...遍历会输出可枚举的属性
[Fn].call([this],[param]...)
fn.call:当前实例(函数Fn)通过原型链的查找机制,找到Function.prototype上的call方法
fn.call():把找到的call方法执行
当call执行的时候,内部处理了一些事情
call中的细节(适用于apply和bind)
apply
:和call基本上一模一样,唯一区别在于传参的方式。apply把需要传递给FN的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于FN接受的是数组的每一项,而不是整个数组。
bind
:预处理this;提前改变this指向,但是FN不立即执行;bind的传参和call方式传参一致,需要一个个向里传。
fn.call(obj,10,20); //改变fn中的this,并且把fn立即执行
fn.bind(obj,10,20); //改变fn中的this,此时的fn并没有执行(不兼容IE6~8)
标签:基本数据类型 工厂 box 包括 修改 实参 构造 属性的方法 apply
原文地址:https://www.cnblogs.com/wangxingren/p/10223994.html