《javascript设计模式》笔记之第四章

一:首先,一个简单的继承实例

首先是创建一个父类Person:



function Person(name) {
  this.name = name;
}

Person.prototype.getName = function() {
  return this.name;
}
下面是创建一个子类Author,用于继承Person:
分两步,第一步继承父类的属性,第二部继承父类的公共方法


function Author(name, books) {
  Person.call(this, name); // 通过这一行代码可以继承父类的属性
  this.books = books; // 子类增添自己的属性
}

Author.prototype = new Person(); // 继承父类方法的第一行代码
Author.prototype.constructor = Author; // 继承父类方法的第二行代码
Author.prototype.getBooks = function() { // 子类增添自己的方法
  return this.books;
};

这样就完成了一个简单的继承

二:编写一个extend函数来简化类的声明

extend函数:
function extend(subClass, superClass) {
  var F = function() {};
  F.prototype = superClass.prototype;
  subClass.prototype = new F();
  subClass.prototype.constructor = subClass;
}

extend的函数作用有两个,一为简化代码,二就是使继承父类方法的时候不用运行父类的构造函数然后Author这个子类的定义就变成了这样:

function Author(name, books) {
  Person.call(this, name);
  this.books = books;
}
extend(Author, Person);

Author.prototype.getBooks = function() {
  return this.books;
};

到目前为止,我们要调用超类的方法,是要以Person开头来调用的(例如:Person.call。。。。等),如果我们想要通过Author开头来调用父类的方法,我们就要对extend函数做一些改动改进的extend函数:

function extend(subClass, superClass) {
  var F = function() {};
  F.prototype = superClass.prototype;
  subClass.prototype = new F();
  subClass.prototype.constructor = subClass;

  subClass.superclass = superClass.prototype;
  if(superClass.prototype.constructor == Object.prototype.constructor) {
    superClass.prototype.constructor = superClass;
  }
}

利用上面的倒数第五行代码,我们就可以使子类可以调用通过Author.这种方法调用父类的方法了(这样做是为了不让Person出现在Author类的定义中),然后我们就可以把Author的定义改成以下:

function Author(name, books) {
  Author.superclass.constructor.call(this, name);
  this.books = books;
}
extend(Author, Person);

Author.prototype.getBooks = function() {
  return this.books;
};

Author.prototype.getName = function() {
  var name = Author.superclass.getName.call(this);
  return name + ‘, Author of ‘ + this.getBooks().join(‘, ‘);
};

这样的话,Author的定义中,除了extend函数中有出现过Person,其他地方都没有出现Person了~三: 原型式继承接下来,我们使用原型式继承来重新设计Person和Author:首先,clone函数(按照书上的顺序,这个可以先不看):

function clone(object) {
    function F() {}
    F.prototype = object;
    return new F;
}

步骤一(定义Person原型):

var Person = {
  name: ‘default name‘,
  getName: function() {
    return this.name;
  }
};

步骤二(通过原型式继承,创建Author原型):

var Author = clone(Person);
Author.books = []; // Default value.
Author.getBooks = function() {
  return this.books;
}

步骤三(使用):

var author = [];

author[0] = clone(Author);
author[0].name = ‘Dustin Diaz‘;
author[0].books = [‘JavaScript Design Patterns‘];

author[1] = clone(Author);
author[1].name = ‘Ross Harmes‘;
author[1].books = [‘JavaScript Design Patterns‘];

author[1].getName();
author[1].getBooks();

通过这样的方法,传统意义的类就变成这样一个个的对象了!(虽然在javascript中类也是对象。。。)这种方法的特点就是所有对象共用一个对象原型,其实就是这么简单。但是这导致的一个问题就是读和写的不对等。下面例子说明这个问题:

var authorClone = clone(Author);
alert(authorClone.name); // 调用的其实是Person.name
                         // 所以输出的是字符串‘default name‘.
authorClone.name = ‘new name‘; // 这样做其实就是在自己的对象中创建一个name属性
alert(authorClone.name); // 这样再使用name属性的时候,就会变成使用自己的name属性,而不是原型上的Person.name了
                         // 所以这时候的值是‘new name‘
authorClone.books.push(‘new book‘); // 对于数组也就是一样的道理,这行代码没有创建自身的books属性,等于直接操作原型里面的属性,所以就会导致原型的默认值编程‘new book’了,这会作用到其他使用原型继承的其他对象当中
authorClone.books = []; // 所以解决的方法就是在自身的对象中新建一个books数组
authorClone.books.push(‘new book‘); // 然后再进行对数组的操作
提示,通过hasOwnProperty可以去分对象的实际成员和它继承而来的成员
此外,上述的这种情况对于拥有对象属性的原型来说也是一样,其实我们也可以用同一种办法来解决,例如下面这个实例:




var CompoundObject = {
  string1: ‘default value‘,
  childObject: {
    bool: true,
    num: 10
  }
}

var compoundObjectClone = clone(CompoundObject);

// 这样做的话就会破坏原型的默认值了
compoundObjectClone.childObject.num = 5;

// 这个解决方法和上面数组那个一样,在自身的原型里面创建一个心的childObject对象
compoundObjectClone.childObject = {
  bool: true,
  num: 5
};

但是,问题又来了,我想要知道默认值的情况下创建自身的childObject对象要怎样做呢?下面就是一种解决方法,利用工厂方法来创建自身的childObject



var CompoundObject = {};
CompoundObject.string1 = ‘default value‘,
CompoundObject.createChildObject = function() {//这个函数是关键,返回一份副本
  return {
    bool: true,
    num: 10
  }
};
CompoundObject.childObject = CompoundObject.createChildObject();//这里就在原型里面先获取一次这个对象副本,原型就有了childObject属性

var compoundObjectClone = clone(CompoundObject);
compoundObjectClone.childObject = CompoundObject.createChildObject();//这里就创建新对象自己的childObject属性
compoundObjectClone.childObject.num = 5;

四: 类式继承和原型式继承的对比类式继承的优点就是很多人都知道原型式继承的优点就是代码简洁,并且节约内存(因为如果克隆出来的对象不新建自己的属性的话,那么就只有原型上的一份公共副本而已)五: 继承与封装

如果要继承的话,最好父类使用门户大开方法

六: 掺元类javascript中只能继承一个父类,所以如有一些不需要严格继承,但是很多类都用到的方法,我们就通过扩充的方式让这些类共享这些方法,例子:一个类(其实就是包含一个简单的toJSONString方法):

var Mixin = function() {};
Mixin.prototype = {
  serialize: function() {
    var output = [];
    for(key in this) {
      output.push(key + ‘: ‘ + this[key]);
    }
    return output.join(‘, ‘);
  }
};

我们很多类都需要用到上面这个类的serialize方法,所以我们就用扩充函数来扩充需要这个方法的类(扩充函数的具体代码下面会给出):

augment(Author, Mixin);

让后就可以使用了:

var author = new Author(‘Ross Harmes‘, [‘JavaScript Design Patterns‘]);
var serializedString = author.serialize();

现在给出augment函数的具体代码:

function augment(receivingClass, givingClass) {
  for(methodName in givingClass.prototype) {
    if(!receivingClass.prototype[methodName]) {
      receivingClass.prototype[methodName] = givingClass.prototype[methodName];
    }
  }
}

其实就是遍历有没有同名的方法,没有的话就添加到要扩展的类中。如果想要只扩展某些方法,而不是全部方法,那么就改进一下augment函数:

function augment(receivingClass, givingClass) {
  if(arguments[2]) { // Only give certain methods.
    for(var i = 2, len = arguments.length; i < len; i++) {
      receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
    }
  }
  else { // Give all methods.
    for(methodName in givingClass.prototype) {
      if(!receivingClass.prototype[methodName]) {
        receivingClass.prototype[methodName] = givingClass.prototype[methodName];
      }
    }
  }
}

改进的augment函数可以选传第三个以后的参数,这些参数都是方法名。然后函数会检测有没有选传的参数,如果有的话就只扩展与这些参数同名的方法。否则扩展全部方法。七: 示例:就地编辑

下面就是使用一个例子,来演示上所说的三种方法。
例子说明:假设你的任务就是编写一个用于创建和管理就地编辑域的可重用的模块化API(就地编辑是指网页上的一段普通文本被点击后就变成一个配有一些按钮的表单域,以便用户对这段文本进行编辑)。使用这个API,用户应该能够为对象分配一个唯一的ID值,能够为它提供一个默认值,并且能够指定其在页面上的目标位置。用户还应该在任何时候都可以访问到这个域的当前值,并且可以选择具体使用的编辑域(比如多行文本框或单行文本框)。
也就是说,平时是这个样子的:

点击之后会变成这样在的:   

文本框中填写"改变文本",save后:

接下来,我们的需求更改了,要把input框变成textarea框,怎么办了?也就是说
点击之后要变成这样子:


方法一:类式继承解决方案
首先创建一个父类EditInPlaceField以及演示它的使用:
<html>

<head>
    <meta http-equiv="charset" content="utf-8"></head>

<body>
    <script>
        //类的定义
        function EditInPlaceField(id, parent, value) {
            this.id = id;
            this.parentElement = parent;
            this.value = value || ‘default value‘;

            this.createElements(this.id);
            this.attachEvents();
        }

        EditInPlaceField.prototype = {
            createElements: function (id) {
                this.containerElement = document.createElement(‘div‘);
                this.parentElement.appendChild(this.containerElement);

                this.staticElement = document.createElement(‘span‘);
                this.containerElement.appendChild(this.staticElement);
                this.staticElement.innerHTML = this.value;

                this.fieldElement = document.createElement(‘input‘);
                this.fieldElement.type = ‘text‘;
                this.fieldElement.value = this.value;
                this.containerElement.appendChild(this.fieldElement);

                this.saveButton = document.createElement(‘input‘);
                this.saveButton.type = ‘button‘;
                this.saveButton.value = ‘Save‘;
                this.containerElement.appendChild(this.saveButton);

                this.cancelButton = document.createElement(‘input‘);
                this.cancelButton.type = ‘button‘;
                this.cancelButton.value = ‘Cancel‘;
                this.containerElement.appendChild(this.cancelButton);

                this.convertToText();
            },
            attachEvents: function () {
                var that = this;
                this.staticElement.addEventListener(‘click‘, function () {
                    that.convertToEditable();
                },false);
                this.saveButton.addEventListener(‘click‘, function () {
                    that.save();
                },false);
                this.cancelButton.addEventListener(‘click‘, function () {
                    that.cancel();
                },false);
            },
            convertToEditable: function () {
                this.staticElement.style.display = ‘none‘;
                this.fieldElement.style.display = ‘inline‘;
                this.saveButton.style.display = ‘inline‘;
                this.cancelButton.style.display = ‘inline‘;

                this.setValue(this.value);
            },
            save: function () {
                this.value = this.getValue();
                this.convertToText();
            },
            cancel: function () {
                this.convertToText();
            },
            convertToText: function () {
                this.fieldElement.style.display = ‘none‘;
                this.saveButton.style.display = ‘none‘;
                this.cancelButton.style.display = ‘none‘;
                this.staticElement.style.display = ‘inline‘;

                this.setValue(this.value);
            },

            setValue: function (value) {
                this.fieldElement.value = value;
                this.staticElement.innerHTML = value;
            },
            getValue: function () {
                return this.fieldElement.value;
            }
        }

        //类的使用
        var body = document.body;
        var titleClassical = new EditInPlaceField(‘titleClassical‘, body, ‘Title Here‘);
    </script></body>

</html>

接下来,就演示如何通过继承来把input装换成textarea框,增添的代码如下:

        function extend(subClass, superClass) {
            var F = function () {};
            F.prototype = superClass.prototype;
            subClass.prototype = new F();
            subClass.prototype.constructor = subClass;

            subClass.superclass = superClass.prototype;
            if (superClass.prototype.constructor == Object.prototype.constructor) {
                superClass.prototype.constructor = superClass;
            }
        }

        //继承
        function EditInPlaceArea(id, parent, value) {
            EditInPlaceArea.superclass.constructor.call(this, id, parent, value);
        };
        extend(EditInPlaceArea, EditInPlaceField);

        EditInPlaceArea.prototype.createElements = function (id) {
            this.containerElement = document.createElement(‘div‘);
            this.parentElement.appendChild(this.containerElement);

            this.staticElement = document.createElement(‘p‘);
            this.containerElement.appendChild(this.staticElement);
            this.staticElement.innerHTML = this.value;

            this.fieldElement = document.createElement(‘textarea‘);
            this.fieldElement.value = this.value;
            this.containerElement.appendChild(this.fieldElement);

            this.saveButton = document.createElement(‘input‘);
            this.saveButton.type = ‘button‘;
            this.saveButton.value = ‘Save‘;
            this.containerElement.appendChild(this.saveButton);

            this.cancelButton = document.createElement(‘input‘);
            this.cancelButton.type = ‘button‘;
            this.cancelButton.value = ‘Cancel‘;
            this.containerElement.appendChild(this.cancelButton);

            this.convertToText();
        };
        EditInPlaceArea.prototype.convertToEditable = function () {
            this.staticElement.style.display = ‘none‘;
            this.fieldElement.style.display = ‘block‘;
            this.saveButton.style.display = ‘inline‘;
            this.cancelButton.style.display = ‘inline‘;

            this.setValue(this.value);
        };
        EditInPlaceArea.prototype.convertToText = function () {
            this.fieldElement.style.display = ‘none‘;
            this.saveButton.style.display = ‘none‘;
            this.cancelButton.style.display = ‘none‘;
            this.staticElement.style.display = ‘block‘;

            this.setValue(this.value);
        };

        var AreaObject = new EditInPlaceArea(‘AreaObject‘, body, ‘多行文本框默认值‘);

继承之后,再重写相应的方法,就完成了所有需求了。


方法二:原型式继承解决方案
第一步:
<html>

<head>
    <meta http-equiv="charset" content="utf-8"></head>

<body>
    <script>
        function clone(object) {
            function F() {}
            F.prototype = object;
            return new F;
        }

        var EditInPlaceField = {
            configure: function (id, parent, value) {
                this.id = id;
                this.value = value || ‘default value‘;
                this.parentElement = parent;

                this.createElements(this.id);
                this.attachEvents();
            },
            createElements: function (id) {
                this.containerElement = document.createElement(‘div‘);
                this.parentElement.appendChild(this.containerElement);

                this.staticElement = document.createElement(‘span‘);
                this.containerElement.appendChild(this.staticElement);
                this.staticElement.innerHTML = this.value;

                this.fieldElement = document.createElement(‘input‘);
                this.fieldElement.type = ‘text‘;
                this.fieldElement.value = this.value;
                this.containerElement.appendChild(this.fieldElement);

                this.saveButton = document.createElement(‘input‘);
                this.saveButton.type = ‘button‘;
                this.saveButton.value = ‘Save‘;
                this.containerElement.appendChild(this.saveButton);

                this.cancelButton = document.createElement(‘input‘);
                this.cancelButton.type = ‘button‘;
                this.cancelButton.value = ‘Cancel‘;
                this.containerElement.appendChild(this.cancelButton);

                this.convertToText();
            },
            attachEvents: function () {
                var that = this;
                this.staticElement.addEventListener(‘click‘, function () {
                    that.convertToEditable();
                }, false);
                this.saveButton.addEventListener(‘click‘, function () {
                    that.save();
                }, false);
                this.cancelButton.addEventListener(‘click‘, function () {
                    that.cancel();
                }, false);
            },

            convertToEditable: function () {
                this.staticElement.style.display = ‘none‘;
                this.fieldElement.style.display = ‘inline‘;
                this.saveButton.style.display = ‘inline‘;
                this.cancelButton.style.display = ‘inline‘;

                this.setValue(this.value);
            },

            save: function () {
                this.value = this.getValue();
                this.convertToText();
            },

            cancel: function () {
                this.convertToText();
            },
            convertToText: function () {
                this.fieldElement.style.display = ‘none‘;
                this.saveButton.style.display = ‘none‘;
                this.cancelButton.style.display = ‘none‘;
                this.staticElement.style.display = ‘inline‘;

                this.setValue(this.value);
            },

            setValue: function (value) {
                this.fieldElement.value = value;
                this.staticElement.innerHTML = value;
            },
            getValue: function () {
                return this.fieldElement.value;
            }
        };

        var body = document.body;
        var titlePrototypal = clone(EditInPlaceField);
        titlePrototypal.configure(‘titlePrototypal ‘, body, ‘Title Here‘);
    </script></body>

</html>

第二步继承,添加的代码:

        var EditInPlaceArea = clone(EditInPlaceField);

        EditInPlaceArea.createElements = function (id) {
            this.containerElement = document.createElement(‘div‘);
            this.parentElement.appendChild(this.containerElement);

            this.staticElement = document.createElement(‘p‘);
            this.containerElement.appendChild(this.staticElement);
            this.staticElement.innerHTML = this.value;

            this.fieldElement = document.createElement(‘textarea‘);
            this.fieldElement.value = this.value;
            this.containerElement.appendChild(this.fieldElement);

            this.saveButton = document.createElement(‘input‘);
            this.saveButton.type = ‘button‘;
            this.saveButton.value = ‘Save‘;
            this.containerElement.appendChild(this.saveButton);

            this.cancelButton = document.createElement(‘input‘);
            this.cancelButton.type = ‘button‘;
            this.cancelButton.value = ‘Cancel‘;
            this.containerElement.appendChild(this.cancelButton);

            this.convertToText();
        };
        EditInPlaceArea.convertToEditable = function () {
            this.staticElement.style.display = ‘none‘;
            this.fieldElement.style.display = ‘block‘;
            this.saveButton.style.display = ‘inline‘;
            this.cancelButton.style.display = ‘inline‘;

            this.setValue(this.value);
        };
        EditInPlaceArea.convertToText = function () {
            this.fieldElement.style.display = ‘none‘;
            this.saveButton.style.display = ‘none‘;
            this.cancelButton.style.display = ‘none‘;
            this.staticElement.style.display = ‘block‘;

            this.setValue(this.value);
        };

        //使用
        var editInPlaceArea = clone(EditInPlaceArea);
        editInPlaceArea.configure(‘editInPlaceArea ‘, body, ‘editInPlaceArea‘);

这样就完成了,其实,相对于第一种方法,改动是很少的~。


方法三:掺元类解决方案
先把扩展类复制进代码中:
function augment(receivingClass, givingClass) {
        if (arguments[2]) { // Only give certain methods.
                for (var i = 2, len = arguments.length; i < len; i++) {
                        receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
                }
        } else { // Give all methods.
                for (methodName in givingClass.prototype) {
                        if (!receivingClass.prototype[methodName]) {
                                receivingClass.prototype[methodName] = givingClass.prototype[methodName];
                        }
                }
        }
}

然后创建一个包含了所有要共享的方法的类:

var EditInPlaceMixin = function() {};
EditInPlaceMixin.prototype = {
    createElements: function(id) {
        this.containerElement = document.createElement(‘div‘);
        this.parentElement.appendChild(this.containerElement);

        this.staticElement = document.createElement(‘span‘);
        this.containerElement.appendChild(this.staticElement);
        this.staticElement.innerHTML = this.value;

        this.fieldElement = document.createElement(‘input‘);
        this.fieldElement.type = ‘text‘;
        this.fieldElement.value = this.value;
        this.containerElement.appendChild(this.fieldElement);

        this.saveButton = document.createElement(‘input‘);
        this.saveButton.type = ‘button‘;
        this.saveButton.value = ‘Save‘;
        this.containerElement.appendChild(this.saveButton);

        this.cancelButton = document.createElement(‘input‘);
        this.cancelButton.type = ‘button‘;
        this.cancelButton.value = ‘Cancel‘;
        this.containerElement.appendChild(this.cancelButton);

        this.convertToText();
    },

    attachEvents: function() {
        var that = this;
        this.staticElement.addEventListener(‘click‘, function() {
            that.convertToEditable();
        }, false);
        this.saveButton.addEventListener(‘click‘, function() {
            that.save();
        }, false);
        this.cancelButton.addEventListener(‘click‘, function() {
            that.cancel();
        }, false);
    },

    convertToEditable: function() {
        this.staticElement.style.display = ‘none‘;
        this.fieldElement.style.display = ‘inline‘;
        this.saveButton.style.display = ‘inline‘;
        this.cancelButton.style.display = ‘inline‘;

        this.setValue(this.value);
    },

    save: function() {
        this.value = this.getValue();
        this.convertToText();
    },

    cancel: function() {
        this.convertToText();
    },
    convertToText: function() {
        this.fieldElement.style.display = ‘none‘;
        this.saveButton.style.display = ‘none‘;
        this.cancelButton.style.display = ‘none‘;
        this.staticElement.style.display = ‘inline‘;

        this.setValue(this.value);
    },

    setValue: function(value) {
        this.fieldElement.value = value;
        this.staticElement.innerHTML = value;
    },
    getValue: function() {
        return this.fieldElement.value;
    }
};

下一步就是创建一个EditInPlaceField类,然后扩展它

function EditInPlaceField(id, parent, value) {
    this.id = id;
    this.value = value || ‘default value‘;
    this.parentElement = parent;

    this.createElements(this.id);
    this.attachEvents();
};
augment(EditInPlaceField, EditInPlaceMixin);

像第一种方法一样使用

var body = document.body;
var titleClassical = new EditInPlaceField(‘titleClassical‘, body, ‘Title Here‘);

将input框变成textarea的做法如下:首先创建EditInPlaceArea构造方法:

        function EditInPlaceArea(id, parent, value) {
            this.id = id;
            this.value = value || ‘default value‘;
            this.parentElement = parent;

            this.createElements(this.id);
            this.attachEvents();
        };

添加要重写的方法:

        EditInPlaceArea.prototype.createElements = function (id) {
            this.containerElement = document.createElement(‘div‘);
            this.parentElement.appendChild(this.containerElement);

            this.staticElement = document.createElement(‘p‘);
            this.containerElement.appendChild(this.staticElement);
            this.staticElement.innerHTML = this.value;

            this.fieldElement = document.createElement(‘textarea‘);
            this.fieldElement.value = this.value;
            this.containerElement.appendChild(this.fieldElement);

            this.saveButton = document.createElement(‘input‘);
            this.saveButton.type = ‘button‘;
            this.saveButton.value = ‘Save‘;
            this.containerElement.appendChild(this.saveButton);

            this.cancelButton = document.createElement(‘input‘);
            this.cancelButton.type = ‘button‘;
            this.cancelButton.value = ‘Cancel‘;
            this.containerElement.appendChild(this.cancelButton);

            this.convertToText();
        };
        EditInPlaceArea.prototype.convertToEditable = function () {
            this.staticElement.style.display = ‘none‘;
            this.fieldElement.style.display = ‘block‘;
            this.saveButton.style.display = ‘inline‘;
            this.cancelButton.style.display = ‘inline‘;

            this.setValue(this.value);
        };
        EditInPlaceArea.prototype.convertToText = function () {
            this.fieldElement.style.display = ‘none‘;
            this.saveButton.style.display = ‘none‘;
            this.cancelButton.style.display = ‘none‘;
            this.staticElement.style.display = ‘block‘;

            this.setValue(this.value);
        };

最后才是扩展:

augment(EditInPlaceArea, EditInPlaceMixin);

使用:

var AreaObject = new EditInPlaceArea(‘AreaObject‘, body, ‘多行文本框默认值‘);

其实这种方法用在这个例子上是不是很适合的,因为上面那两个类都很相似,导致要先重写一些方法再扩展。












时间: 2024-11-06 03:40:10

《javascript设计模式》笔记之第四章的相关文章

javascript高级程序设计 第十四章--表单脚本

javascript高级程序设计 第十四章--表单脚本 在HTML中表单由<form>元素表示,在js中表单对应的是HTMLFormElement类型,这个类型也有很多属性和方法:取得表单元素的引用还是为它添加id特性,用DOM操作来获取表单元素:提交表单:把<input>或<button>元素的type特性设置为"submit",图像按钮把<input>元素的type特性设置为"image",也可以调用submit(

APUE学习笔记:第四章 文件和目录

4.1 引言 本章将描述文件的特征和文件的性质 4.2 stat.fstat和lstat函数 #include<sys/stat.h> int stat(const char *restrict pathname,struct stat *restrict buf); int fstat(int filedes,struct stat *buf) int lstat(const char *restrict pathname,struct stat *restrict buf); 三个函数的返

2014年软考程序员-常考知识点复习笔记【第四章】

51CTO学院,在软考备考季特别整理了"2014年软考程序员-常考知识点复习笔记[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考程序员-常考知识点复习笔记[汇总篇]  4.串 串一章需要攻破的主要堡垒有: 1. 串的基本概念,串与线性表的关系(串是其元素均为字符型数据的特殊线性表),空串与空格串的区别,串相等的条件; 2. 串的基本操作,以及这些基本函数的使用,包括:取子串,串连接,串替换,求串长等等.运用串的

【MySQL】《高性能MySQL》学习笔记,第四章,Schema与数据类型优化

[MySQL]<高性能MySQL>学习笔记,第四章,Schema与数据类型优化 良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询语句来设计schema. 反范式的设计可以加快某些类型的查询,单同时可能使另一类型的查询变慢,比如添加计数表和汇总表是一种很好的优化查询的方式,但这些表的维护成本可能会很高. 1.选择优化的数据类型 更小的通常更好. ? 应该尽量使用可以正确存储数据的最小类型,更小的数据类型通常更快,因为他们占用更少的磁盘,内存和CPU缓存,并且处理时需要的CPU周

【读书笔记】第四章 瞬时响应:网站的高性能架构

第四章 瞬时响应:网站的高性能架构 4.1 网站性能测试 4.1.1 不同视角下的网站性能 1.用户角度:网站响应速度快还是慢2.开发人员:关注系统本身及其子系统的性能,响应时间,吞吐量,并发能力,稳定性等指标.3.运维人员:关注基础设施和资源利用率,比如贷款能力,服务器配置,数据中心网络架构等. 4.1.2 性能测试指标 1.响应时间 下表是一些常用的系统操作所需要的响应时间 2.并发数:系统能够同时处理的请求数目3.吞吐量:单位时间内,系统处理的请求数量(注意与并发数区分).TPS(每秒事务

javascript - 工作笔记 (事件四)

在javascript - 工作笔记 (事件绑定二)篇中,我将事件的方法做了简单的包装, JavaScript Code 12345   yx.bind(item, "click", function (e) {         //console.log("Div Click 1 !");         alert("Div Click 1 !");         e.stopPropagation();     }); 但是这样用起来有些

Thinking In Java笔记(第四章 控制执行流程)

第四章 控制执行流程 Java中使用了C的所有流程控制语句.在Java中涉及的关键字包括if-else,while,do-while,for,return,break,continue以及选择语句switch.然而Java不支持goto语句(该语句引起了许多的反对意见),但是Java仍然可以类似goto那样跳转. 4.1 True和False 所有的条件语句都利用条件表达式的真假来决定执行的路径.Java中不允许我们将一个数字作为boolean值使用,虽然C和C++中是允许的("非零"

数学建模学习笔记(第四章:5个静态优化实例分析学习)

 第四章:静态优化模型(微分法建模,求导得目标函数最优解) 现实世界中普遍存在着优化问题:静态优化模型指求解问题的最优解:重点是如何根据目的确定恰当的目标函数:一般使用微分法. 1.    存储模型:存在某种矛盾,寻找平衡最优点! a)      问题描述:配件厂为装配生产若干中产品,轮换产品时因更换设备要付生产准备费,产量大于需求时因积压资金要付存储费,该场生产能力非常大,即所需数量可在很短时间内产出. b)     问题存在:今已知某产品的日需求量为100件,生产准备费5000元,存储费为每

JavaScript高级程序设计学习笔记第十四章--表单

1.在 HTML 中,表单是由<form>元素来表示的,而在 JavaScript 中,表单对应的则是 HTMLFormElement 类型. HTMLFormElement 继承了 HTMLElement,因而与其他 HTML 元素具有相同的默认属性. 2.HTMLFormElement的独特属性和方法: acceptCharset:服务器能够处理的字符集:等价于 HTML 中的 accept-charset 特性. action:接受请求的 URL:等价于 HTML 中的 action 特