基本包装类型
- String Number Boolean区别(string number boolean)
- 1.创建字符串对象
var str1 = new String('demo');
console.log(typeof str1)// object
var str2 = String('deme');
console.log(typeof str2)//string
var str3 = 'demo';
console.log(typeof str3)//string
- 2.创建数值对象
var num1 = new Number(10)//object
var num2 = Number(20)//number
var num3 = 10 // number
- 3.创建布尔对象
var bool1 = new Boolean(true)//object
var bool2 = Boolean(true);//boolean
var bool3 = true// boolean
- 4.特殊的创建方式
var str4 = new Object('demo');
var num4 = new Object(10);
var bool4 = new Object(true);
- 5.使用的注意点
- 引用类型和值类型对比的时候,引用类型会默认调用tostring转换为 再进行判断对比
var str1 = new String('dd');//0x123 var str2 = new String('dd');//0x456 var str3 = 'demo'; console.log(str1 == str2);//fasle console.log(str1 === str2);//false // 引用类型和值类型对比的时候,引用类型会默认引用tostring 再进行判断对比 console.log(str1 == str3);//true console.log(str1=== str3);//false
- 基本数据类型为什么可以访问属性?
- 1.字符串, 数值, 布尔 在访问属性或调用方法的时候
- 2.默认会创建一个新的对象与之相对应
- 3.利用该对象访问属性或者调用方法,得到结果后返回
- 4.销毁该对象
var str4 = 'demo111'; str4.des = 'des'; console.log(str4.length); console.log(str4.des);//undefined var str5 = new String('demo111'); str5.des = 'des'; console.log(str5.des)//des
- 面试题
Number.prototype.sum = function(){ console.log(this+20) } var num1 = new Number(10); num1.sum();//30 var num2 = 10; num2.sum();//30 (10).sum();//30
- 注意点
- 给基本包装类型的原型对象动态添加属性和方法,那么所有基本数据类型可以即时获取,原理同上,但当行代码过后,就会被销毁
Object.prototype 的属性和方法
- 1.constructor 指向对应的构造函数
- 2.hasOwnProperty 判断对象中是否存在指定的实例属性
- 3.isPrototypeof 判断一个对象是否是指定的对象的原型对象
- 判断包含是原型链上的原型对象
function Person(){ } var obj{ des:'des' } Person.prototype = obj; var p1 = new Person(); console.log(obj.isPrototypeOf(p1));//true console.log(Object.prototype.isPrototypeOf(p1));//true
- 4.propertyIsEnumerable 判断一个属性是否可枚举,如果属性石可枚举的,就可以通过for..in遍历
var obj = { name:'zs', age:20 } // 获取一个属性的描述信息 console.log(Object.getOwnPropertyDescript(obj,'name')); // 设置name 为不可枚举 Object.defineProperty(obj,'name',{ enumerable : false }) for(var k in obj){ console.log(obj[k]) } 添加判断是否可枚举代码 console.log(obj.propertyIsEnumerable('name')); // false
- 5.toString 返回对应的字符创描述信息
- 1.object 对象- > '[object object]'
- 2.数组|函数 -> 对应的字符创形式
- 3.Number 在使用的时候可以传参,表示进制转换
var obj = {name: 'zs'} var arr1 = [1,2,3]; function fun() { } console.log(obj.toString());//'[object,object]' console.log(arr1.toString());//'1,2,3' console.log(fun.toString());//fun(){} 字符串 var num = new Number(20); console.log(num.toString(8)); // 24 4*1 + 2*8 = 4 + 16 = 20 console.log(num.toString(3));// 202 2*1 + 0*3 + 2*3*3 = 2 + 18 = 20 console.log(num.toString(6));// 32 2*1 + 3 * 6 = 2 + 18 = 20
- 6.toLocateString 大部分情况等价于toString, 特殊情况下会做本地化处理
- 7.valueOf 返回对应的值
- 1.object对象返回本身
- 2.基本包装类型返回对应的基本数据类型的值
- 3.如期对象返回时间戳
var obj = { name : 'zs' } console.log( obj.valueOf());//obj对象本身 var str1 = new String('demo'); var num1 = new Number(10); var bool1 = new Boolean(true); console.log(typeof str1.valueOf()); // demo console.log(typeof num1.valueOf()); // 10 console.log(typeof bool1.valueOf()); // true var date = new Date(); console.log(date.valueOf()); // 1526179038533 时间戳 (ms) // 计算机元年到现在 1970 1 1
静态成员和实例成员
- 实例成员: 直接添加在实例上的属性和方法
- 原型成员: 直接添加到原型上的属性和方法
- 静态成员: 直接添加到构造函数上的属性和方法(构造函数本质也是一个对象,也可以拥有自己的属性和方法)
function Person(){
this.name = '默认';
var age = 10; //不是实例成员
}
Person.prototype.des ='des';
var p1 = new Person();
// 静态成员
Person.des = '描述函数';
Person.log = function () {
console.log('log');
}
Object的静态成员(属性和方法)
-
1.Object.apply 借用其他对象的方法
-
2.Object.assign 拷贝属性
-
3.Object.arguments 函数内部的隐藏参数,用来接收实参,保存实参
function fun(){ // arguments 不是数组,是一个类似于数组点的结构 console.log(arguments[1]); console.log(Array.isArray(arguments)//false } fun(1,2,3,4,5,6,7)
-
4.Object.call 借用其他对象的方法
-
5.Object.create 创建一个新的对象,并设置原型对象
-
6.Object.caller 返回一个函数,返回调用当前函数的函数
- 在全局中调用,返回null
function test1(){ console.log(test1.caller);//返回调用test1的函数 } function test2(){ test1() } test2() console.log(test1.caller)//null
-
7.Object.constructor 指向对应的构造函数
-
8.Object.getOwnPropertyDescriptor 获取对象中某个实例属性的描述信息
- Object..getOwnPropertyDescriptor(要获取的对象,要获取的属性)
- configurable: 是否可配置(1.是否可删除2.是否可以修改该配置包含value,writable,configurable)
- enumerable 是否可枚举
- value 值
- writable 是否可修改
var obj = { name : 'zs', age : 20 } Object.defineProperty(obj,'name',{ configurable : true, enumerable : false, writable : false, value : 'zs' }) //writable 可修改 obj.name = 'ls'; console.log(obj); // configurale 可配置 console.log(delete obj.name); console.log(obj); // enumerable 可枚举 for(var key in obj){ console.log(key); }
-
9.Object.defineProperty 定义一个属性,并设置这个属性的描述信息
- Object.defineProperty(要操作的对象,要操作的属性,描述对象)
- 1.如果修改已经存在的属性默认是true
- 2.如果添加新的属性,默认是false
var obj = { name : 'zs' } console.log(Object.getOwnPropertyDescriptor(obj, 'name')); Object.defineProperty(obj,'age',{ }) console.log(Object.getOwnPropertyDescriptor(obj, 'age'));
-
10.Object.getOwnPropertyNames 获取实例属性的属性名 返回数组,数组存放所有的属性名
-
11.Object.keys 获取实例属性名(可枚举属性,不包括不可枚举) 返回数组,数组存放所有的属性名
-
12.Object.getPrototypeof 获取一个对象的原型对象
-
==13*.Object.preventExtensions 禁止扩展(不能添加,可以删除和修改)==
- Object.isExtensible 判断一个对象是否是可扩展的
-
==14*.Object.seal 密封对象 (不能添加,不能删除,可以修改)==
- 密封对象让对应的对象不能添加新的属性,同时旧有的属性不能删除,但是可以修改已有属性的可枚举性,可配置型,可写性,可修改已有属性的值
- Object.isSealed 判断一个对象是否是密封的
-
==15*.Object.freeze 冻结对象
不能添加属性,不能删除,不能修改==
这个方法比 Object.seal 更绝,冻结对象是指那些不能添加新的属性,不能修改已有属性的值,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性的对象。也就是说,这个对象永远是不可变的.
- Object.isFrozen 判断一个对象是否是冻结的
Function构造函数的使用
- Function 的参数一定是字符串
- 不传参,创建出来的是空函数
- 传1个参数,这个参数作为函数体
- 传多个参数, 前面的是形参列表,最后一个是函数体
var fun = new Function('a','b','console.log(a+b);')
fun3(1,2);
- 注意点
- 1.函数.name 获取函数名,可以获取,函数名不能修改
处理函数参数过长的问题(Function构造函数使用)
- 1.使用+ 拼接
- 2.使用``包括 反括号
- 3.使用JS模板
函数的隐藏参数
-
arguments: 函数内部的隐藏参数,用来接收是从哪并保存实参( 保存的不是一个数组.与数组结构类似)
-
函数调动: 默认会把实参赋值给形参,并把实参保存在arguments中
-
实参> 形参 会一次赋值,超出的实参可以通过arguments获取到
-
实参< 形参, 会依次赋值,没有赋值为undefined
-
arguments.length : 实参的长度
-
函数名.length : 形参的长度
function fun () {
console.log(arguments[0]);
}
callee 和caller
-
1.callee 函数内部arguments有一个callee,返回函数自身,常用于匿名函数的递归调用
-
2.caller 返回调用当前函数的函数
- 在全局作用域调用返回null;
-
递归调用
- 自己调用自己
- 要有退出条件
// 使用arguments.callee匿名函数的递归调用
求1到n的和
(function (n){
if(n ==1 ){
return 1;
}
return arguments.callee(n-1)+n
}
)(10);
Function小应用(数组去重和求最大值)
- 用arguments来获取数组的数据,来进行遍历
- indexOf: 返回元素对应的索引,如果该元素不存在,返回-1
- 求数组去重
var fun = new Function(` var arr = []; for (var i = 0; i < arguments.length; i++) { if(arr.indexOf(arguments[i]) == -1){ arr.push(arguments[i]); } } return arr;`)
console.log(fun(9, 12, 3, 4, 5, 3, 5, 2, 3));
```
- 求最大值
function fun() { var maxNum = arguments[0]; for (var i = 1; i < arguments.length; i++) { if(maxNum < arguments[i]){ maxNum = arguments[i]; } } return maxNum; } console.log(fun(1, 2, 3, 4, 89, 67, 98, 2, 3));
==Function.prototype原型链==
- 两个点: Object.prototype 作为对象的时,他的原型对象被修改了,指向null
- Function.prototype 作为对象的时,他的原型对象被修改了,它指向Object.prototype
Object和Function 的关系
- 1.Object和Function 互为对方的实例
- 2.JS中的对象都是基于Object
- 3.instanceof 的原理
- 判断构造函数的原型对象是不是在实例对象的原型链上
私有变量和私有函数
- 定义在构造函数内部的变量和函数,在外界无法直接访问
- 特权方法: 可以访问私有变量和私有函数的实例方法
function Person() {
this.name = 'zs';
var age = 20;
var logAge = function(){
console.log(age);
}
//特权方法:可以访问私有变量和私有函数的实例方法
this.test = function(){
return age;
}
this.test2 = function(){
logAge() ;
}
var p1 = new Person();
console.log(p1.text());
p1.text2();
}
eval函数
-
可以把字符串转为对应的JS代码
-
并且马上执行
-
eval 和Function 的区别
- 1.都可以把字符串转为对应的JS代码
- 2.eval 把字符串转为代码后会马上执行;Function要调用
-
eval处理JSON数据
- JSON数据: 一种轻量级的数据结构,可以用来表示数据,保存数据,传输数据,本质是一个字符串
- JSON操作:
- 1.把JSON字符串转为对应的对象(JSON.parse)(eval) (反序列化处理)
- 2.把对象转为JSON数据(JSON.stringify)(序列化处理)
-
建议:不建议使用(JS是词法作用域,eval可以动态调整词法作用域,性能不好)
with简单说明
- 可以把对象的作用域引申到大括号中
- 作用是为了减少代码量
var obj = {
name:'zs',
age:20,
des:'des'
}
with(obj){
name= 'ls';
age = 21;
des = '22';
obj.log = 'log';
}
-
使用注意点:
- 1.不能使用无前缀的方式添加属性
- 2.this指向window
- 3.严格模式禁止使用
-
以往场合:当需要深层次的引用
-
使用建议: 不建议使用,用即时函数体可以替代
==函数内部this的指向==
- 函数内部this的指向取决于函数的调用方式
- 1.函数作为对象方法调用时,this指向当前的对象
- 2.作为普通函数直接调用,this指向window
- 3.使用new构造函数调用时,this指向构造函数内部新创建的对象
- 4.利用call和apply来借用方法时(函数上下文调用),this指向实际调用方法的对象
var obj = {
name: 'zs',
showName:function (){
console.log(this);
}
}
obj.showName();// this -->obj
var fun = obj.showName;
fun(); // this -> window
function Person() {
console.log(this);//p1
}
var p1 = new Person;
- this的丢失问题
- 原因: 函数的调用方式发生改变
var obj = {
age :20,
show: function(){
console.log(this.age)
}
}
obj.show();
var fun = obj.show;
fun(); // this丢失问题undefined
-
用document调用getElementById 这个方法时,内部的this指向document,直接调用,this指向window
-
调用document.getElementById这个方法时,函数内部的this始终绑定document
调用document.getElementById这个方法时,函数内部的this始终绑定document
var getEEle = (function(func){
return function(){
return func.apply(document,arguments);
}
}
)(document.getElementById)
var div = getEle('demo');
console.log(div);
网友评论