Archive六月 2018

Javascript中的location对象

  • window.location === document.location // true
  • location的属性列表
  • 修改location的属性会导致页面刷新并产生新的历史记录
  • window.location = “URL” 和 location.href=”URL”效果一样,都会调用location.assign(URL)
  • location.replace(URL)不会产生新的历史记录,而且会禁用后退
  • location.reload(true): 重新加载页面,参数可以选择是否从服务器加载(而不是从缓存加载)

Javascript中的window对象

window对象的两个作用:

  • 表示浏览器的一个实例
  • ECMAscript中的Global对象
    直接定义Global变量与在window上定义Global变量的区别是:直接定义的Global变量的[[configurable]]特性为false,也就是说,它不能用delete删除

窗口关系及框架

  • 如果html中包含框架(frame),那么每个框架都有自己的window对象,它们从上到下,从左到右,依次存放于window.frames数组中。可以通过window.frames[index]或者window.frames[frame_name]来获取frame的window对象
  • window.name为frame的name
  • top对象表示最外层html的window对象
  • parent对象表示上层frame的window对象
  • self表示frame自身的window对象

窗口位置

  • window.screenLeft window.screenTop 或者firefox中的window.screenX window.screenY表示窗口左上角的位置
     
     
        var left = (typeof window.screenLeft == "number") ? window.screenLeft: window.screenX;
        var top = (typeof window.screenTop == "number") ? window.screenTop: window.screenY;
       
  • window.outerHight window.outerWidth 表示窗口的高和宽
  • window.innerHight window.innerWidth 表示页面视图的高和宽

打开新窗口

  • window.open(URL, target, args, is_replace)
    URL: 新窗口打开的网址
    target: 目标frame的名字,或者_self, _parent,_top,_blank
    args: is_replace: 是否替代当前窗口
  • window.close() : 关闭一个窗口
  • window.closed: 布尔值,window是否已经关闭
  • window.opener: 表示打开本窗口的窗口window对象

超时调用与间歇调用

  • var id = setTimeout(function, ms)  ; clearTimeout(id);
  • var id = setInterval(function, ms) ; clearInterval(id);

系统对话框

  • alert(‘string’)
  • var boolean = confirm(“string”);
  • var result_string = prompt(“string”, “default_answer”);

Javascript中的函数表达式

  • 函数声明 有提升 而函数表达式没有,因此不应该通过if…else来声明函数
     
     
        if (condition) {
            function sayHi() {}
        } else {
            function sayHi() {}
        }
       
  • 在递归函数中使用arguments.callee可以避免因函数名改变产生的错误。
     
     
        function factorial(num) {
            if (num 
                return 1;
            } else {
                return num * arguments.callee(num - 1);
            }
        }
       
  • 闭包是指函数中定义的函数,闭包的作用域链中包含父函数的执行环境(变量对象),所以即使父函数退出,如果闭包仍然被引用,那么父函数的变量对象就一直存在于内存中。所以,过度的使用闭包会导致内存占用过多
  • 闭包的另外一个副作用是闭包只能取得父函数中变量的最后一个值,例如:
     
     
        function createFunctions() {
            var result = new Array();
            for(var i = 0; i < 10; i++) {
                result[i] = function() {
                    return i;
                }
            }
            return result;
        }
       

    调用result中的每个函数都会返回10

  • 闭包如果是匿名函数,则该函数中的this指向全局对象
  • 可以用定义一个立即执行函数来模仿块级作用域:
     
     
            (function(){
            //块级作用域                                   
            })();                                        
       

Javascript中的对象

属性的类型

1.1 数据类属性

数据类属性的属性——特性为:

  • [[Configurable]]: 默认为true。表示能否通过delete删除属性,能否修改属性的特性。
  • [[Enumerable]]: 默认为true。表示在用for-in迭代对象时,能否迭代出该属性。
  • [[Writable]]: 默认为true。表示能否修改属性的值。
  • [[Value]]: 默认为undefined。保存属性的值。

1.2 访问器类属性

访问器类属性的特性为:

  • [[Configurable]]: 默认为true。表示能否通过delete删除属性,能否修改属性的特性。
  • [[Enumerable]]: 默认为true。表示在用for-in迭代对象时,能否迭代出该属性。
  • [[Get]]: 默认为undefined。读取属性时调用的函数。
  • [[Set]]: 默认为undefined。写入属性时调用的函数。

使用访问器类型的属性的常用方法是写入该属性时往往会导致其他属性也跟着变化。

 

1.3 对特性的操作方法:

Object.defineProperty(Object, propertyName, {attributes}): 设置属性的特性。
Object.defineProperties(Object, {propertyName: {attributes},}): 设置多个属性的特性。
Object.getOwnPropertyDescriptor(Object, propertyName);

 

创建对象的方法

2.1 工厂模式

 
 
function createPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}
var sen = createPerson('sen', 19, 'programer');

缺点:无法识别一个对象属于哪一个类

 
 
alert(sen instanceof createPerson) // false

2.2 构造函数模式

 
 
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function() {
        alert(this.name);
    }
}
var sen = new Person("sen", 19, "programer");
alert(sen instanceof Person) // true
alert(sen.constructor === Person) // true

缺点:每个对象都会有独立的函数定义

 
 
var sen1 = new Person("sen1", 19, "player");
alert(sen1.sayName == sen.sayName) // false

2.3 原型模式

 
 
function Person() {
}
Person.prototype.name = "sen";
Person.prototype.age = "19";
Person.prototype.job = "programer";
Person.prototype.sayName = fucntion() {
    alert(this.name);
}
var sen = new Person();
Person.prototype.constructor === Person // true
Person.prototype.isPrototypeOf(sen) // true
Object.getPrototypeOf(sen) === Person.prototype // true
sen.hasOwnProperty("name") // false
"name" in sen // true

判断属性是不是在原型对象中:

 
 
!sen.hasOwnProperty("name") && ("name" in sen)

原型模式更简洁的写法:

 
 
function Person(){};
Person.prototype = {
    constructor = Person,
    name: "sen",
    age: 19,
    job: "programer",
    sayName: function() {
        alert(this.name);
    }
}
Object.defineProperty(Person.prototype, {
    enumerable: false,
    value: Person
});

缺点:

1. 省略了传递初始化参数
2. 如果原型中的属性为引用类型,则所有对象会共用这个引用类型

2.4 组合使用构造模式和原型模式

 
 
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
}
Person.prototype.sayName = function() {
    alert(this.name)
}

缺点: 构造函数和原型是独立的

2.5 动态原型模式

 
 
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    if (typeof this.sayName !== "function") {
        Person.prototype.sayName = function() {
            alert(this.name);
        };
    }
}

2.6 寄生构造函数模式

 
 
function Person(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}
var sen = new Person('sen', 19, 'programer');

寄生构造函数模式一般用于创建特殊的引用类型。例如,创建一个包含toPipedString方法的数组类型。

 
 
function SpecialArray() {
    var arr = new Array();
    arr.push.apply(arr, arguments);
    arr.toPipedString = function() {
        return this.join(" | ");
    }
    return arr;
}
var colors = new SpecialArray("red", "black");
alert(colors.toPipedString());

缺点和工厂模式一样,都无法被instanceof识别

2.7 稳妥构造函数模式

与寄生构造函数类似,区别在于:

  • 不使用this给类添加公共属性
  • 创建对象时不使用new关键字
 
 
  1. function Person(name, age, job) {
  2. var o = new Object();
  3. o.sayName = function() {
  4. alert(name);
  5. }
  6. return o;
  7. }
  8. var sen = Person('sen', 19, 'programer');

缺点和工厂模式一样,都无法被instanceof识别

继承

3.1 原型链

 
 
function SuperType() {
    this.property = true;
}
SuperType.prototype.getSuperValue = function() {
    return this.property;
}
function SubType() {
    this.subProperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function() {
    return this.subProperty;
}
var obj = new SubType();
alert(obj instanceof SubType) // true
alert(obj instanceof SuperType) // true
alert(obj instanceof Object) // true

缺点:

  • SuperType中的属性如果为引用类型,所以的子类都会共用该属性
  • 创建子类时,如果给父类传递参数,会影响其他的子类

3.2 构造函数继承继承

 
 
function SuperType() {
    this.colors = ['black', 'red'];
}
function SubType() {
    SuperType.call(this);
}

缺点:函数无法复用

3.3 组合继承

 
 
function SuperType(name) {
    this.name = name;
    this.colors = ['black', 'red'];
}
SuperType.prototype.sayName = function() {
    return this.name;
}
function SubType(name) {
    SuperType.call(this, name);
}
SubType.prototype = new SuperType();

3.4 原型式继承

 
 
var person = {
    name: "sen"
}
var newPerson = Object.create(person, {name: {
    value: "yang"
}});

缺点: 原型式继承仅仅是对父类做了一个浅拷贝,并加入了子类自己的属性。所以问题和原型链相同,父类中的引用类型属性会被所有子类共用。

3.5 寄生式继承

 
 
function createAnother(obj) {
    var clone = Object.create(obj);
        clone.sayHi = function() {
        alert('hi');
    }
    return clone;
}

缺点: 函数不能复用

3.6 寄生组合式继承 (常用)

 
 
function inheritPrototype(subType, superType) {
    var prototype = Object.create(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
function SuperType(name) {
    this.name = name;
    this.colors = ['red', 'black'];
}
SuperType.prototype.sayName = function() {
    alert(this.name);
}
function SubType(name) {
    SuperType.call(this, name);
    this.age = age;
}
inheritPrototype(SubType, SuperType);
"