目录
扩展原型上的方法
扩展String.prototype.trim这个方法,让它兼容IE8及以下
if (!String.prototype.trim) {
String.prototype.trim = function () {
// console.log(this, 'IE8及以下');
var re = /^\s+|\s+$/g;
return this.replace(re, '');
}
}
var str = ' 星期一 ';
console.log('(' + str.trim() + ')');
扩展数组的indexOf方法,兼容IE8及以下
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (val, index) {
// this --> arr
index = typeof index === 'undefined' ? 0 : index;
for (var i = index; i < this.length; i++) {
if (this[i] === val) {
return i;
}
}
return -1;
}
}
var arr = [4, 3, 2, 43, 32, 3, 3];
console.log(arr.indexOf(3)); // 1
console.log(arr.indexOf(3, 2)); // 5
创建对象的方法
1、字面量方法
var person1 = {
name: 'zs',
age: 3,
fn: function () {
console.log('前端');
}
}
var person2 = {
name: 'ls',
age: 5,
fn: function () {
console.log('后端码农');
}
}
不足:这种创建方式,适用于单个对象的创建,如果要创建多个对象,会代码冗余。
2、实例创建
var person1 = new Object(); // {}
person1.name = 'zjl'; // 给对象赋值
person1.age = 18;
person1.fn = function () {
console.log('加油');
}
console.log(person1);
不足:要创建多个对象,会产生代码冗余
3、工厂模式创建对象
function person(name, age) {
// 1、原料
var obj = new Object();
// 2、生产
obj.name = name;
obj.age = age;
obj.fn = function () {
console.log('前端开发');
}
// 3、出厂
return obj;
}
var p1 = person('zs', 3);
console.log(p1);
优点:适合批量创建
不足:识别问题,因为根本无法搞清楚他们到底是哪个对象的实例。
4、创建对象-构造函数
构造函数创建对象
构造函数的特点:
1、构造函数名首字母大写(为了区分普通函数,不是必须,是约定)
2、构造函数方法没有显示的创建对象(new Object())
3、直接将属性和方法赋值给 this 对象
4、没有 return 语句,不需要返回对象
5、通过构造函数创建对象,必须使用 new 运算符调用(直接调用跟普通函数一样)
function Person(name, age) {
this.name = name;
this.age = age;
this.fn = function () {
console.log('前端开发');
}
}
var p1 = new Person('zs', 3);
console.log(p1);
当用new调用一个构造函数,实际上会经历以下四步
(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。
优点:解决了识别问题
不足:一模一样的函数,在内存中会创建多次,存在浪费内存空间的问题
5、创建对象-原型方法
function Person() { }
// console.log(Person.prototype); // 只要创建一个函数,它就会有原型对象 {constructor: f}
Person.prototype.name = 'zs';
Person.prototype.age = 3;
Person.prototype.fn = function () {
console.log('前端开发');
}
var p1 = new Person();
console.log(p1);
console.log(p1.name); // zs 为什么能访问到原型上的name,因为原型上的属性和方法对所有的实例共享
p1.fn();
console.log(p1.toString);
console.log(p1.abc);
原型链:对象查找属性的过程,先找自身,如果自身找到了,则返回这个属性,如果自身没有,则顺着原型链找到上一级原型,如果上一级原型还是没有,则继续向上找,一直找到Object的原型,如果Object的原型也没有,则报undefined。
原型创建对象解决了构造函数重复创建同一个函数的问题
不足:不能传参,创建的对象一样
6、混合模式创建对象
// 构造函数和原型的混合(创建对象的标准方法)
// 属性写在构造函数中,方法写在原型上
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.showName = function () {
console.log(this.name);
}
Person.prototype.showAge = function () {
console.log(this.age);
}
var p1 = new Person('zs', 3);
console.log(p1);
console.log(p1.name); // zs
p1.showName();
var p2 = new Person('ls', 5);
console.log(p2);
7、创建对象-动态混合
function Person(name, age) {
this.name = name;
this.age = age;
if (!Person.prototype.showName) {
Person.prototype.showName = function () {
console.log(this.name);
}
Person.prototype.showAge = function () {
console.log(this.age);
}
}
}
var p1 = new Person('zs', 3);
console.log(p1);
var p2 = new Person('ls', 5);
console.log(p2);