js创建对象的6种方法
1、对象字面量方法
var person ={
name: "qinqin",
age: 24,
family: ["fanfan","ningning","lingling"],
say: function(){
console.log(this.name);
}
};
2、new操作符+Object创建对象
var person = new Object();
person.name = "qinqin";
person.age = 24;
person.family = ["fanfan","ningning","lingling"];
person.say = function(){
console.log(this.name);
}
以上两种方法在使用同一接口创建多个对象时,会产生大量重复代码,为了解决此问题,工厂模式被开发。
3、工厂模式
function createPerson(name,age,family){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.family = family;
obj.say = function(){
console.log(this.name)
}
return obj;
}
var person1 = createPerson('qinqin',24,['fanfan','ningning','lingling'])
var person2 = createPerson('qin',24,['fan','ning','ling'])
console.log(person1 instanceof Object); //true
工厂模式解决了重复实例化多个对象的问题,但没有解决对象识别的问题(但是工厂模式却无从识别对象的类型,因为全部都是Object,不像Date、Array等,本例中,得到的都是obj对象,对象的类型都是Object,因此出现了构造函数模式)。
4、构造函数
function Person(name,age,family){
this.name = name;
this.age = age;
this.family = family;
this.say = function(){
console.log(this.name)
}
}
var person1 = new Person("qinqin",24,["fanfan","ningning","lingling"]);
var person2 = new Person("qin",24,["fan","ning","ling"]);
console.log(person1.constructor); //constructor 属性返回对创建此对象的数组、函数的引用
对比工厂模式有以下不同之处:
1、没有显式地创建对象
2、直接将属性和方法赋给了 this 对象
3、没有 return 语句
以此方法调用构造函数步骤:
1、创建一个新对象
2、将构造函数的作用域赋给新对象(将this指向这个新对象)
3、执行构造函数代码(为这个新对象添加属性)
4、返回新对象 ( 指针赋给变量person ??? )
可以看出,构造函数知道自己从哪里来(通过 instanceof 可以看出其既是Object的实例,又是Person的实例)
构造函数也有其缺陷,每个实例都包含不同的Function实例( 构造函数内的方法在做同一件事,但是实例化后却产生了不同的对象,方法是函数 ,函数也是对象)
因此产生了原型模式
5、原型模式
function Person() {
}
Person.prototype.name = "qinqin";
Person.prototype.age = 24
Person.prototype.family = ["fanfan","ningning","lingling"];
Person.prototype.say = function(){
alert(this.name);
};
console.log(Person.prototype); //Object{name: 'qinqin', age: 24, family: Array[3]}
var person1 = new Person(); //创建一个实例person1
console.log(person1.name); //lisi
var person2 = new Person(); //创建实例person2
person2.name = "qin";
person2.family = ["fan","ning","ling"];
console.log(person2); //Person {name: "qin", family: Array[3]}
// console.log(person2.prototype.name); //报错
console.log(person2.age); //24
原型模式的好处是所有对象实例共享它的属性和方法(即所谓的共有属性)
6、混合模式(构造函数+原型模式)
function Person(name,age,family){
this.name = name;
this.age = age;
this.family = family;
}
Person.prototype = {
constructor: Person, //每个函数都有prototype属性,指向该函数原型对象,原型对象都有constructor属性,这是一个指向prototype属性所在函数的指针
say: function(){
console.log(this.name);
}
}
var person1 = new Person("qinqin",24,["fanfan","ningning","lingling"]);
console.log(person1);
var person2 = new Person("you",21,["fan","ning","ling"]);
console.log(person2);
js创建数组的方法
1、字面量创建数组
var arr = [];
arr[0]='a';
arr[2]='c';
console.log(arr,arr.length)
2、new操作符+Array
var arr = new Array()
arr[0]=1;
arr[1]=10;
console.log(arr)
一般使用字面量创建数组的方法
数组常用的方法eES1998(es3.0)
1、改变原数组(push,pop,shift,unshift,sort,reverse,splice)
push:往数组的最后一位添加数据,并返回数组的长度
模仿系统的push方法
var arr = [1,2,3]
Array.prototype.push = function(){
for(var i = 0; i < arguments.length; i++){
this[this.length] = arguments[i]
}
return this.length;
}
pop:把数组的最后一位剪切,并返回被剪切的元素
unshift:往数组的前面添加数据,并返回数组长度
shift:把数组的第一位剪切,(不传参数,传了也没有用)并返回被剪切的元素
sort:数组排序
var arr = [1,10,3,4,6]
//1、必须写两个参数
//2、看返回值 1)当返回值为负数时,那么前面的数放在前面
// 2)为正数,那么后面的数在前面
// 3)为0,不动
arr.sort(function(a,b){
return a-b //升序
})
arr.sort(function(a,b){
return b-a //降序
})
reverse:逆转数组的顺序
splice:arr.splice(从第几位开始,截取多少的长度,在切口处添加新的数据) 第一位传负数,表示倒数第一位
2、不改变原有数组(concat,join,split(是字符串的方法,写在这里是为了和join相比较),toString,slice)
concat:连接两个数组
slice:截取数组,取头不取尾
join:把数组分割成字符串,arr.join()如果括号不传东西,按逗号隔开;arr.join('')直接拼接字符串
数组新增的方法(es5.0) ES2009
2个索引方法:indexOf() 和 lastIndexOf();
5个迭代方法:forEach()、map()、filter()、some()、every();
forEach()没有return
let arr = ['apple','orange','tomato']
arr.forEach(function(item,index,arr){
console.log(item,index,arr)
})
map()非常有用,做数据的交互‘映射’,正常情况下,需要配合return,返回是一个新数组,可以任意修改成自己想要的格式。若没有return,相当于forEach。
let arr = ['apple','orange','tomato']
let arr1 = arr.map(function(item,index,arr){
var json = {
name:item
}
return json;
})
filter()过滤,过滤一些不合格‘元素’,如果回调函数返回true,就留下来
let arr = [{title:'aaa',grade:1},
{title:'bbb',grade:1},
{title:'ccc',grade:3},
{title:'eee',grade:2}]
let arr1 = arr.filter(function(item,index,arr){
return item.grade == 1
})
some()类似查找,数组里面某一个元素符合条件,返回true
every()数组里面所有的元素都符合条件,返回true
注意:平时只要用map(),一定要有return
2个归并方法:reduce()、reduceRight();
let arr = [1,2,3,4,5,6]
let arr1 = arr.reduce(function(prev,cur){
return prev + cur
})
es6.0新增的方法ES2015
for…of…
arr.keys()数组下标
arr.entries()数组某一项
let arr = ['apple','b','city']
for(let [key,val] of arr.entries()){
console.log(key,val)
}
Array.from()用于类似数组的对象(即有length属性的对象)和可遍历对象转为真正的数组。
Array.of()将一组值转变为数组。
find()和findIndex()用于找出第一个符合条件的数组成员。参数是个回调函数,所有数组成员依次执行该回调函数,直到找到第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,就返回undefined;可以接收3个参数,依次为当前值、当前位置、原数组。
es7.0新增的方法ES2016
includes()表示某个数组是否包含给定的值,如果包含则返回 true,否则返回false。可以接收两个参数:要搜索的值和搜索的开始索引。当第二个参数被传入时,该方法会从索引处开始往后搜索(默认索引值为0)。若搜索值在数组中存在则返回true,否则返回false。
tips:includes与indexOf的区别是:前者返回布尔值(利于if条件判断),后者返回数值。
类数组
1、可以利用属性名模拟数组的特性;
2、可以动态的增长length属性;
3、如果强行让类数组调用push方法,则会根据length属性值得位置进行属性的扩充;
必须具备的特性:属性要为索引(数字)属性,必须有length属性,最好加上push
好处:把对象的属性和数组拼写到一起
var obj = {
'0':'a',
'1':'b',
'2':'c',
'length':3,
'push':Array.prototype.push,
'splice':Array.prototype.splice
}
来源:oschina
链接:https://my.oschina.net/u/4384923/blog/4268484