三目运算符
判断?表达式:表达式
var str = '89'>'9'?'you are right':'you wrong';//字符串比较大小会从左到右一位一位比较。
console.log(str);//you are wrong;
浅拷贝
var person = {
name:'张三',
age:10,
sex:'male',
height:180,
weight:120
}
var person2 = {};
for(var k in person){
person2[k]= person[k];
}
console.log(person,person2)//此时是浅拷贝,虽然值都拷贝过来了。如果person里有一个数组或者对象。
//那么修改person2的值,person的值也会发生改变。因为person2复制过来的是引用地址。
Object.prototype.num = 1;
var person = {
name:'张三',
age:10,
sex:'male',
bro:{
first:'张一',
second:'张er'
}
}
var person2 ={};
for(var k in person){
person2[k] = person[k];//此时因为bro这个属性是对象,bro里存着的是这个对象的引用地址.
}
person2.bro.third = '李四';
console.log(person ,person2);
深拷贝
// hasOwnProperty 自身有该属性则返回true 否则返回false;
function deepClone(origin, target) {
var tar = target || {},//如果不传target就赋值为{};
toStr = Object.prototype.toString,
arrType = '[object Array]';
for (var k in origin) {//遍历
if (origin.hasOwnProperty(k)) {//是否是自身属性
if (typeof origin[k] === 'object' && origin[k] != null) {//是对象且不是null
if (toStr.call(origin[k]) === arrType) {//是否是数组
tar[k] = [];
} else {
tar[k] = {};
}
deepClone(origin[k], tar[k]);//如果是这样。递归实现
} else {
tar[k] = origin[k];//原始值。直接赋值。
}
}
}
return tar;
}
/**
* 1 判断是否自身有这个属性 hasOwnProperty
* 2 有 就判断这个属性值是否是对象(需要排除null) 是就判断是数组还是 对象。
* 3 是数组或者对象都要 调用自身。
* 4 返回tar
*/
var person = {
name: '123',
age: 122,
son: {
name: 'lucy',
son: {
name:'John'
}
},
cars: ['Mazda', 'Benz'],
eat:function () {
console.log('i am eating an apple');
}
}
var person2 = deepClone(person);
person2.eat = function () {
console.log('i am eating an orange');
}
person2.cars.push('XiaoPeng');
console.log(person,person2);
笔试题
题目一
/**
* AO {
* foo:undefined->2
* }
*
*/
function test(){
console.log(foo);//undefined
var foo = 2;
console.log(foo);//2
console.log(a);//a 并未在作用域内申明 a.is not defined
}
test();
题目二
var name = '222';
var a = {
name: '111',
say:function () {
console.log(this);
console.log(this.name);
}
}
var fun = a.say;
fun();//222 将a.say 赋值给fun fun在全局。this指向window.
a.say();//111 对象中调用this 指向该对象。
var b = {
name: '333',
say:function (fun) {
fun();
}
}
b.say(a.say);//222 此时相当于 b.say(function(){console.log(this);console.log(this.name)});相当于fun 变量。
b.say = a.say;//将a.say赋值给b.say;
b.say();//333 对象中调用this this指向该对象。
题目三
function test() {
var marty = {
name: 'marty',
print:function () {
console.log(this.name);
}
}
var test1 = {
name: 'test1'
}
var test2 = {
name:'test2'
}
var test3 = {
name:'test3'
}
test3.print = marty.print;
marty.print.call(test1);//test1 this的指向改变成了 test1
marty.print.apply(test2);//test2 this的指向改变成了test2
marty.print();//marty
test3.print();//test3 this的指向改变成了test3
}
test();
题目四
var bar = {
a:'1'
}
function test() {
bar.a = 'a';
Object.prototype.b = 'b';//函数终极原型链 b
return function () {
console.log(bar.a);
console.log(bar.b);
}
/**
* 相当于 声明了一个函数。并且将这个函数return 出去。此时形成了闭包
*/
}
test()();
作业
function Foo() {
getName = function () {
console.log(1);
}
return this;//构造函数会隐式返回this 如果不是构造函数这个this 指向就是window
}
//给Foo函数新增一个静态属性。Function也是对象。类似于var obj = {}; obj.getName = function(){.....}
Foo.getName = function () {
console.log(2);
}
//Foo原型上添加一个getName属性
Foo.prototype.getName = function () {
console.log(3);
}
//函数表达式
var getName = function (params) {
console.log(4);
}
//函数申明
function getName(params) {
console.log(5)
}
//对象调用自身的方法
Foo.getName();//2
//全局调用 因为函数声明提前了。函数表达式又把函数重新赋值
getName();//4
//()的优先级比.高 Foo()执行的时候把getName 重新赋值了。
Foo().getName();//1
// .的优先级比new高所以先执行Foo.getName();->new 2 new 一个数字没有含义。
new Foo.getName();//2
// new+一个函数()这个组合。new Foo()返回一个新的实例化对象。实例化对象没有getName().所以就往原型上找.
new Foo().getName();//3
//相当于new (new Foo()).getName(); new this.getName()//原型链上找getName; new 3是没有意义的。
new new Foo().getName();// 3