第四章 变量,作用域和内存问题
基本类型和引用类型的区别
1.基本类型不能直接添加属性
引用类型可以直接添加属性:
var person = new object();
person.name = "dengzhu";
2.复制的区别
var num1 = 10;
var num2 = num1;
基本数据类型是新建一块内存赋值
、、、、、、、、
var person1 = new object();
var person2 = person1;
对象是将person1的内存地址给person2,一起指向Object();(堆栈原理)
3.函数传参的区别
如果局部变量为基本类型,函数内的变化不改变其值 ,用完就扔
var num=10;
function add(number){
number = number +1;
return number;
}
var result = add(num);//输出为11;
console.log(num);//<b>输出为10,值没有变
即不改变 基本类型 形参的值
、、、、、、、、、、
如果形参的值为对象,函数内的改变会改变形参的值
function setName(obj){
obj.name = "dengzhu"
}
var person = new Object();
alert(person.name);//输出为dengzhu 发生了改变
4.instanceOf用于检测对象
typeOf可以检测数据类型
instanceof只能用于检测是否为对象
var person = new Object();
console.log(person instanceof Object);//返回为true 如果不是对象则返回的是false
/
//
/
/
/
/
执行环境及作用域
执行环境分为两种: 全局环境 局部环境(函数)
全局作用域与局部作用域:
1.内部环境可以访问全局环境的变量,全局环境不能用局部环境的变量。(子能用父的变量,父不能用子的变量)
2.没有块级作用域: for,if等循环语句中声明的变量不会用完就消失,相当于全局变量。
3.声明的变量:在局部环境中声明的变量如果 没有用var 声明 直接赋值 就被当做全局变量。
垃圾收集:每隔一段时间都会将不再继续使用的变量内存清除
方法一:标记清除(主要)
1.将存储在内存中的所有变量都打上标记
2.将环境中的变量和变量的标记去掉
3.之后内存再被打上标记的标量就会被删除
方法二:引用计数(搞不懂)
内存管理的方法:接触不必要用的内存
如 变量 = null;
、
、
、
、
、
第五章 引用类型
Object类型
引用类型定义:将数据和功能组织在一起
对象是引用类型Object的一个实例
对象的分类
对象创建方法 :
第一种 var obj = {
uname:‘dengzhu’,//属性的创建,多个属性创建之间用逗号隔开
sex: male;
sayHi: function(){//方法的创建, 冒号后面跟function
}
}
用冒号赋值
第二种
var obj = new Object();//创建一个空对象
obj.uname=‘邓柱’ ;
obj.sex=‘男’;
obj.satHi= function(){
}
//用等号赋值
第三种 构造函数
对象的使用
1.对象名.属性
2.对象名[属性或方法]
变量和属性的区别
变量:可以单独使用,要定义变量类型
属性: 不需要定义直接书写,但在对象外不能单独使用,必须对象名.属性
利用构造函数创建对象相当于构建一个类
思路:将对象中公共的方法和属性提取出来构建一个类
function Star(name, age) {
this.name = name;
this.age = age;
this.sing = function(song) {
console.log(song);
}
}
var ldh = new Star('刘德华', 29);
ldh.sing('冰雨');//直接调用对象的方法
console.log(ldh.name);
构造函数相当于一个类
对象可以new 这个 对象产生
属性和方法前必须加this.
遍历函数属性和属性数值for in
通过这个方法可以实现循环
function Star(name, age, music) {
this.name = name;
this.age = age;
this.song = music;
this.sing = function(song) {
console.log(song);
}
}
var ldh = new Star('刘德华', 29, '冰雨');
for (var k in ldh) {
console.log(k);
console.log(ldh[k]);
}
for( var k in 对象名){
console.log(k)为对象中的属性名
console.log()为对象中属性值
}
内置对象
math , date ,Array ,String
for in 用于访问对象中的属性
对象中属性值的比较
var items = [
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'And', value: 45 },
{ name: 'The', value: -12 },
{ name: 'Magnetic' },
{ name: 'Zeros', value: 37 }
];
// sort by value
items.sort(function (a, b) {
return (a.value - b.value)
});
/
/
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
、、、、、、、、、、、、、、、、、、、、、、、、、/、、、
、、、、、、/、、、、、、、、、、、、、、、
、、、、、、、/、、、、/、/、、、、、、、、、
、、、、、、、、、、
Array类型 数组类型
数组中可以保持任何类型的数据
数组类型创建方法
一、
var colors = Array();
var colors = Array();
二、字面量方法创建数组
let colors = [‘1’,‘2’,‘3’];
数组类型的检测:
arr instanceof Array;
字符串类型和数组类型之间的转换
valueOf()方法可以将数组类型的字符串转化为 数组
let str = ['a', 'b', 'c'];
console.log(str.valueOf());
toString()和join()方法能将数组转化为字符串:
join()方法括号内 为 分隔符的字符串形式
let str = ['a', 'b', 'c'];
alert(str.toString);
console.log(str.valueOf());
console.log(str.join('||'));
数组的替换
将某一项替换:
for(let i = 0 ;i<arr.length;i++){
arr[i]='某个值';
}
替换数组第一项
arr[0]=‘某个值’;
替换最后一项
arr[arr.length-1] = ‘某个值’;
数组的增删
栈式增删:先进后出(在末尾操作)
arr.push(): 在数组末尾添加任意数量的数组和字符串,并返回添加后的长度
arr.pop(); :去除数组末尾的最后一项,并返回去除的那一项
队列增删:先进后出 (在开头操作)
arr.shift();:删去数组开头的值,并返回删除的值
arr.unshift();: 在数组开头添加任意数量的字符串 并返回添加后的长度
、、、、、、、、、、、、、、、、、、、、、、、、
数组的排序
arr.reverse(); : 倒叙 将原来的数组 倒过来
arr.sort();:
let arr = ['5', '2', '10'];
function compare2(value1, value2) {
return value2 - value1;//降序排列
}
console.log(arr.sort(compare2));
function compare3(value1, value2) {
return value1- value2;//升序排列
}
console.log(arr.sort(compare3));
数组的方法
一、concat()方法:复制数组 并添加字符到新数组
//数组的复制并添加新的字符: concat()方法
var colors = ['123', '123', '234'];
var colors1 = colors.concat('dengz', ['sdaf', '454']);
console.log(colors1);
splice()方法 在数组中间任意位置的增删 (改变原来的数组)返回的是被增删的项
splice()接收三个参数 (起始位置,要删除的项数,要添加的字符项)
通过splice删除中间任意位置的项 splice(起始位置,要删除的项数 )
通过splice添加任意位置任意项 splice(插入位置 , 0,要添加的任意项)
通过splice替换任意位置任意项 splice(替换的位置, 要替换的项数,替换的值)
//splice的引用
let colors3 = ['123', '345', '567', '89'];
//删除中间任意项
colors3.splice(1, 2); //删除中间亮相
console.log(colors3); // ["123", "89"]
//添加任意项
colors3.splice(1, 0, 'dengzhu', '邓柱');
console.log(colors3); //"123", "dengzhu", "邓柱", "89"]
//替换中间任意项
colors3.splice(1, 2, 'dengzhu', '邓柱');
console.log(colors3); //["123", "dengzhu", "邓柱", "89"]
位置方法:indexof 和 lastindexof() 两个都接受两个参数 :要查找的项和表示查找起点位置的索引(可以不写);找到后就返回索引 没找到返回-1
indexof() : 从前往后查找
lastindexof(): 从后往前查找
//## 位置方法
let test = [1, 2, 3, 11, 21];
console.log(test.indexOf(1)); // 0
console.log(test.lastIndexOf(1)); //0
console.log(test.indexOf(3, 1)); //2(从第二个开始查找的)
数组的筛选 (不对原数组做修改)
every()和 some()类似 every() 是数组中每个数都满足括号中的函数才返回true some()是数组中任意一个项满足函数就就返回true 函数接受三个参数(item数组项,数组项的位置,数组本身)
let numbers = [1, 2, 3, 4, 5, 6, 7];
let result = numbers.every(function(item, index, array) {
return (item > 2);
});
console.log(result); //返回 false
result = numbers.some((item, index, array) => {
return (item > 2);
});
console.log(result); //返回true
filter()函数 查询符合某些条件的数组 他利用指定的函数确定是否在返回时数组中包含某一项,例如要返回一个所有值都大于2的数组
let filterresult = numbers.filter(function(item, index, array) {
return (item >2);
});
console.log(filterresult); //[3, 4, 5, 6, 7]
map()也返回一个数组 这个数组 是 原数组中的每一项都传入函数并运算的结果,可以用来处理数组中的数据
var mapResult = numbers.map(function(item, index, array) {
return (item * 2);
});
console.log(mapResult); //将numbers中的值都乘二[2, 4, 6, 8, 10, 12, 14]
function类型
函数中可以保存一些功能,对象中保留一些属性
创建函数对象
var fn = new function();
函数接收到的是数组参数保存在arguements中,可以用arguements[]访问
如 function howmanywords(string){
console.log(arguements.length);
}
howmantwords("dengzhu"); // 输出1
howmanywords(1,2);//输出为2
函数声明提前
//变量声明提前
console.log(a);
var a = 1; //返回undefined,,但不会报错 但是let 不会变量提前
//函数声明提前,不止函数名声明提前了,整个函数也被创建好了
fn();
function fn() {
console.log('函数声明提前了'); //返回函数声明提前了
}
//函数表达式形式的函数声明不会提前也不会被创建
// fn2(); //报错
var fn2 = function() {
console.log('函数声明提前');
}
对象中添加方法:
//对象中添加方法
let obj = {
//方法一:
sayName: function() {
},
//方法二
sayAge = function() {
}
}
作用域中的查找顺序
//作用于问题:查找顺序:函数作用有就在函数作用遇中查找 再到全局作用遇中
通过函数访问对象中的属性
let arr = [{
id: 10,
name: 'kc'
}, {
id: 8,
name: 'hy'
}, {
id: 15,
name: 'pipi'
}, {
id: 5,
name: 'mama'
}];
arr.sort(function(a, b) {
return (a.id - b.id)
});
console.log(arr.sort());
// console.log(arr.sort()) //[{id:2,name:'mama'},{id:8,name:'hy'},{id:10,name:'kc'},{id:15,name:'pipi'}]
//方法二:创建一个函数返回一个 比较对象某个属性的函数
function createComparisonFunction(propertyName) {
return function(object1, object2) {
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
}
console.log(arr.sort(createComparisonFunction('id')));
尾调用:return值是一个函数
递归 :函数中调用自己:必须用 arguments.callee
//函数中调用函数自己:递归必须要用arguements.callee 来表示原函数
var sum = null;
//得到 阶层的和
function getOneself(num) {
if (num > 1) {
sum = num + arguments.callee(num - 1);
} else {
sum = 0 + num;
}
return sum;
}
console.log(getOneself(4)); //10
caller 返回 函数的调用函数
//caller的应用:返回该函数的调用函数
function outer() {
inner();
}
function inner() {
console.log(inner.caller); //返回outer函数
}
outer();
函数中的属性和方法
length :接收 形参的个数
prototype属性
apply()和 call()方法:在特殊作用域中调用函数,实际上就是设置函数体内this对象的值.
apply()接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组(可以是数组,也可以是arguments对象)。
apply(this, [num1, num2]);
apply(this, arguments);
call() 也接受两个参数 :第一个是this 但第二个参数必须一一列举出来
call(this,num1,num2,num3);
好处:虽然函数和对象没有任何关系 不需要将函数放到对象中去了 只需要将对象中的属性加this 就可以通过call 访问对象中的属性
// 函数的属性与方法 call() apply() 改变this的指向
//好处:虽然函数和对象没有任何关系 不需要将函数放到对象中去了 只需要将对象中的属性加this 就可以通过call 访问对象中的属性
window.color = 'red';
var o = {
color: ' blue'
}
function sayColor() {
console.log(this.color);
}
sayColor.call(this); //red this默认指向了全局
sayColor.call(window); //red this 指向了全局
sayColor.apply(o); //blue this 指向了 o对象
sayColor.call(o); //blue this 指向了 o对象